This question already has an answer here:
Closed 11 years ago.
Possible Duplicate:
Trying to Access Twitter Streaming API with C
Could anyone help me how do I code in C of getting a stream of tweets? I already have read how to output results through C libcurl get output into a string.
I also know how to get a stream of tweets just through 'curl' in the command terminal. Thanks!
If I understand you're asking for the basic pattern of a CURL request, which I personally thought was not that well written in the tutorial. It seemed like a dozen lines of code should provide the basic pattern for how to use CURL, but I didn't see it written like that in a tutorial. Hope this helps:
CURL *handle;
char PostFields[512];
/* initialise curl */
curl_global_init( CURL_GLOBAL_ALL )
handle = curl_easy_init();
/* set options to post */
curl_easy_setopt( handle, CURLOPT_URL, TwitterUrl );
curl_easy_setopt( handle, CURLOPT_POST, 1 );
sprintf( PostFields, "user_id=%s?screen_name=%s", TwitterId, TwitterName );
curl_easy_setopt( handle, CURLOPT_POSTFIELDS, (void*)PostFields );
curl_easy_setopt( handle, CURLOPT_POSTFIELDSSIZE, strlen( PostFields ) );
/* set options to handle response */
curl_easy_setopt( handle, CURLOPT_HEADERFUNCTION, HandleTwitterHeader );
curl_easy_setopt( handle, CURLOPT_WRITEFUNCTION, HandleTwitterResponse );
/* do the request */
curl_easy_perform( handle );
curl_easy_cleanup( handle );
I'm not sure to understand your question, and I am not sure you are understanding it well.
Perhaps your issue is related to JSON in C. There are several C (& C++) libraries for JSON. You could use jansson
Related
I saw some c codes relative to the topic. I've tried them but only I get errors saying a heap of errors of curl.h. I googled much but couldn't find a good answer. I'm using CCS C compiler version v5.008. I really want to solve this problem soon.
I tried to compile the code from the following link.
enter link description here
#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, "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;
}
Gives me error: "Error 119"C:\Users\Sisitha\Documents\CCS C Projects\ Testing\curl\curlbuild.h" Line 556(145,183): " Unknown non-configure build target" "
I'm on Windows 7(64bit)
Please help me to solve this matter.
Thanks!
curl uses GNU autotools to be built from source. There's a library to be built and configured, for the example program and header file, to link against. The error :
Error 119"C:\Users\Sisitha\Documents\CCS C Projects\ Testing\curl\curlbuild.h" Line 556(145,183): " Unknown non-configure build target"
Suggests that the curl.h you included, hasn't been configured, by the standard GNU ./configure; make; make install build sequence.
Curl installation instructions Install -- how to install curl
I'm tring to POST JSON data to a url from bash using:
$ curl -v -d '{xxx:200}&apikey=xxxxx' -X POST http://localhost/xxxx/input/post.json -H "Accept: application/json" -H "Content-Type:application/json"
And in C using the following:
int main(void)
{
CURL *easyhandle;
curl_global_init(CURL_GLOBAL_ALL);
easyhandle = curl_easy_init();
if(easyhandle) {
char *data="json={xxx:200}&apikey=xxxxx";
curl_easy_setopt(easyhandle, CURLOPT_POSTFIELDS, data);
curl_easy_setopt(easyhandle, CURLOPT_URL, "http://localhost/xxxx/input/post.json");
curl_easy_perform(easyhandle);
curl_easy_cleanup (easyhandle);
}
curl_global_cleanup();
return 0;
}
This is what i'm trying to achieve actually:
http://localhost/xxxx/input/post.json?json={xxx:200}&apikey=xxxxx
It doesn't seem to work. :(
I'm a complete novice to curl. Please help.
Thanks!
Fortunately the server I was sending the data handled POST and GET requests, so the code in question would suffice.
Others with a similar problem can use a simple workaround (If your code doesn't have real time constraints and is not performance intensive). You may fork a bash process using system() from C. This avoids you the trouble of encoding.
What you are trying to do is not performing a POST request but performing a GET request. However, I'm not sure this is a good idea, since GET parameters are limited in length (to something like 2 kB or so), and - as others have already mentioned - they need to be encoded and decoded and all the funky stuff which is a pain in the neck.
The URL pointing to localhost suggests me that you have control over the server code. If you used the POST parameters instead of the GET ones, you could use your current code as-is (which sets the POST body of the request, which is probably the right thing to do -- so you don't have to change your client code, you only have to change the server code.)
I'm developing a system that tracks objects with a P(an)T(ilt)Z(oom) camera which can be controlled via HTTP requests. The C application I develop is supposed to receive position data of the tracked object and to send commands to the camera to control the pan and tilt angle. In addition to these commands the camera has to receive a session refresh command every 5 seconds. HTTP Digest Authorization has to be used for the connection.
I'm sending the HTTP request with libcurl. I figured already out that for digest auth one needs to use on and the same curl handle for all requests in this stackoverflow post.
For sending the session refresh command periodically I tried to use a thread which is just doing this:
while(1)
{
usleep(5000000);
sessionContinue(g_Config.cam_ip);
}
With sessionContinue looking like this:
CURLcode sessionContinue(char* url)
{
CURLcode res;
char requestURL[40];
char referer[47];
struct curl_slist *headers=NULL;
strcpy(requestURL , url);
strcat(requestURL, CAM_SESSION_CONTINUE);
strcpy(referer , "Referer: http://");
strcat(referer , url);
strcat(referer , CAM_MONITOR);
headers = curl_slist_append(headers,"Connection:keep-alive");
headers = curl_slist_append(headers, camCookie);
// In windows, this will init the winsock stuff
curl_global_init(CURL_GLOBAL_ALL);
curl_easy_reset(curl);
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 , requestURL );
curl_easy_setopt( curl , CURLOPT_HTTPHEADER , headers );
curl_easy_setopt( curl , CURLOPT_HTTPGET , 1 );
curl_easy_setopt( curl , CURLOPT_USERNAME , "root" );
curl_easy_setopt( curl , CURLOPT_PASSWORD , "password" );
curl_easy_setopt( curl , CURLOPT_HTTPAUTH , CURLAUTH_BASIC | CURLAUTH_DIGEST );
// 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:%d : %s\n", curl_easy_strerror(res) , __FILE__ , __LINE__ );
}
return res;
}
The application always crashed with segmentation fault after executing curl_easy_perform(curl). So I read the libcurl tutorial again and now I know that using one curl handle in multiple threads is a no go.
What I tried then was to use a timer with SIGALRM to implement the periodic session refresh. This didn't change the problem with the crash at curl_easy_perform(curl). The strange thing is that the application doesn't crash when sending the normal command to control the pan and tilt position which uses the same curl handle. The only difference between session refresh and pan/tilt command is that session refresh uses GET and pan/tilt uses POST.
Are there any other possibilities to send pan/tilt commands continuously with a short pause every 5 seconds used to send the session refresh?
You have a long range of problems in one small program. Here's a few:
You might overflow one of those small fixed-size buffers with the dangerous unbounded C functions you use. Quite likely one of them is the reason for the segfault.
curl_global_init() is documented to be called once, you call it over and over again - this even without calling curl_global_cleanup() in between. You obviously call curl_easy_init() somewhere out of the function and you should move the global init there.
'referer' gets filled with data but is never used otherwise
Another advice is to use CURLOPT_ERRORBUFFER to get error messages in rather than curl_easy_strerror() as you may get some extra details then. And of course to set CURLOPT_VERBOSE while debugging the request to see that things look the way you want it.
Thanks for your comment Daniel Stenberg. I'm now calling curl_global_init() just once when the handle has been set up. referer wasn't really needed here, but I had forgotten to remove it before pasting the code here.
The reason for the segmentation fault was that the session refresh command and the commands for pan and tilt tried to use one and the same curl handle at the same time, which obviously can't really work. So the solution with the timer and SIGALRM wasn't the problem. The segmentation faults have been solved by adding a mutex lock to avoid concurrent accesses to the curl handle.
Hello what I am trying to do is send post method twice, however when I send it a second time the information from the first time is also being included and I do not want that.
To illustrate what I mean, this is the code that sends using post method. (the handle curl was already created)
void process(char* transferBuffer) {
curl_easy_setopt(curl, CURLOPT_URL, "http://localhost/cpp.php");
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, transferBuffer);
res = curl_easy_perform(curl);
if (res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
If I do something like:
process("name=John"); - webserver receives name=John
process("name=El"); - webserver receives name=John AND name=El
What I want to do is somehow clean previously used data;
the curl handle was already created ... What I want to do is somehow clean previously used data
All I can say is that if you want to reuse your curl handle - which is a best practice, you should reset it with curl_easy_reset before re-setting your options and re-performing the transfer.
Note that without the complete sample code (including the creation of your curl handle, etc) it is quite hard to provide a detailed answer.
I want to receive JPEG images from an IP-camera over HTTP. I am using LIBCURL for this purpose in my C program. The camera returns a single image with the following URL:
"http://143.205.116.14?image&res=full&x0=0&y0=0&x1=2944&y1=1920"
Using LIBCURL, I can receive a single image and write it to a .jpg file in the callback function. However, for continuous streaming, the camera accepts a GET request as follows:
"GET /mjpeg&res=full&x0=0&y0=0&x1=2944&y1=1920 HTTP/1.1\r\n HOST:143.205.16.14\r\n\r\n"
I was wondering how do I specify this GET request in libcurl. Is it possible to use in curl_easy_setopt()?
At present I use the following code to get a single image and save in the write_data callback function:
size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {
size_t written;
written = fwrite(ptr, size, nmemb, stream);
return written;
}
int main()
{
curl = curl_easy_init();
if(curl) {
fp = fopen("C:\\trans.txt","wb");
curl_easy_setopt(curl, CURLOPT_URL, "http://143.205.116.14?image&res=full&x0=0&y0=0&x1=2944&y1=1920");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
fclose(fp);
}
How do I use the GET method so that the images are received continuously and saved by the callback function?
I'm not totally sure about this, but I think you must open the connection with CURL specify that the connection will be kept alive and then start downloading data.
With some type of while() you should download data and get each JPEG that the camera sent.
You must read about MJPEG codec, which has a structure where each JPEG is delimited by a header.
Have you tried using the full URL?
http://143.205.116.14/mjpeg&res=full&x0=0&y0=0&x1=2944&y1=1920
libcurl parses this and creates the GET request. GET is the default for HTTP, you have to add some code to get HEAD or POST (so you probably don't want to do that).