Using libcurl from C++

来源:互联网 发布:网络理财排行 编辑:程序博客网 时间:2024/05/16 13:03

Using libcurl from C++

January 3rd, 2006

For a project I’ve been doing at work I’ve been building an RSS reader in C++. Yeah, I know, me .. C++ .. pigs are flying! Still, that miracle aside, the project has been pretty fun. To get a quick jump start, I began by using the PTypes networking classes to retrieve the RSS feeds. This worked out fine for simple cases but began to get complicated when dealing with server redirects, different HTTP versions, etc. So today I unplugged PTypes and replaced it with libcurl. I should have done this from the start. The easyinterface to libcurl makes life.. well. really easy!. And a lot of the cruft I was adding to my code when using PTypes disappeared. This isn’t the fault of PTypes, though. While doing this exercise I wasn’t able to find a simple example of how to wrap libcurl from C++, so I’ve put together one below. I know I could have usedcURLpp but I didn’t want to add the extra dependency since I was not really going to use the object bindings it offers to any great extent.

If you find this program useful, please consider a small donation:

view plaincopy to clipboardprint?
  1. /* 
  2.  * This is a very simple example of how to use libcurl from within 
  3.  * a C++  program. The basic idea is that you want to retrieve the 
  4.  * contents of a web page as a string. Obviously, you can replace 
  5.  * the buffer object with anything you want and adjust elsewhere 
  6.  * accordingly. 
  7.  * 
  8.  * Hope you find it useful.. 
  9.  * 
  10.  * Todd Papaioannou 
  11.  */  
  12.   
  13. #include <string>  
  14. #include <iostream>  
  15. #include "curl/curl.h"  
  16.   
  17. using namespace std;  
  18.   
  19. // Write any errors in here  
  20. static char errorBuffer[CURL_ERROR_SIZE];  
  21.   
  22. // Write all expected data in here  
  23. static string buffer;  
  24.   
  25. // This is the writer call back function used by curl  
  26. static int writer(char *data, size_t size, size_t nmemb,  
  27.                   std::string *buffer)  
  28. {  
  29.   // What we will return  
  30.   int result = 0;  
  31.   
  32.   // Is there anything in the buffer?  
  33.   if (buffer != NULL)  
  34.   {  
  35.     // Append the data to the buffer  
  36.     buffer->append(data, size * nmemb);  
  37.   
  38.     // How much did we write?  
  39.     result = size * nmemb;  
  40.   }  
  41.   
  42.   return result;  
  43. }  
  44.   
  45. // You know what this does..  
  46. void usage()  
  47. {  
  48.   cout < < "curltest: /n" << endl;  
  49.   cout << "  Usage:  curltest url/n" << endl;  
  50. }   
  51.   
  52. /* 
  53.  * The old favorite 
  54.  */  
  55. int main(int argc, char* argv[])  
  56. {  
  57.   if (argc > 1)  
  58.   {  
  59.     string url(argv[1]);  
  60.   
  61.     cout < < "Retrieving " << url << endl;  
  62.   
  63.     // Our curl objects  
  64.     CURL *curl;  
  65.     CURLcode result;  
  66.   
  67.     // Create our curl handle  
  68.     curl = curl_easy_init();  
  69.   
  70.     if (curl)  
  71.     {  
  72.       // Now set up all of the curl options  
  73.       curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);  
  74.       curl_easy_setopt(curl, CURLOPT_URL, argv[1]);  
  75.       curl_easy_setopt(curl, CURLOPT_HEADER, 0);  
  76.       curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);  
  77.       curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);  
  78.       curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);  
  79.   
  80.       // Attempt to retrieve the remote page  
  81.       result = curl_easy_perform(curl);  
  82.   
  83.       // Always cleanup  
  84.       curl_easy_cleanup(curl);  
  85.   
  86.       // Did we succeed?  
  87.       if (result == CURLE_OK)  
  88.       {  
  89.         cout << buffer << "/n";  
  90.         exit(0);  
  91.       }  
  92.       else  
  93.       {  
  94.         cout << "Error: [" << result << "] - " << errorBuffer;  
  95.         exit(-1);  
  96.       }  
  97.     }  
  98.   }  
  99. }  

 


51 Responses to “Using libcurl from C++”

  1. John on June 7, 2006 9:25 pm

    hey!! thanks a lot for this sample code! i have been struggling with libcurl and thinking of moving on to ptypes! but now i can see things way more clear ~! thanks a lot

    Reply

    Luckyspin reply on June 8th, 2006 8:34 am:

    No problem! Glad my little code snippet helped out. I think sticking with libcurl is going to be a big benefit. It’s way more powerful than ptypes when you really get into the nitty gritty of doing http calls.

    Reply

    freakydoc reply on July 29th, 2006 3:17 pm:

    I would like also to thank for your example. Even with the good documentation of CURL, nothing can be so helpful as a simple example. Thanks again.

    Reply

  2. Pitoss on September 21, 2006 2:59 pm

    Thanks thanks thanks, i feel dumb saying this but this post is what i needed to start my own project. (duh, it seems any other samples/tutorials were not enough for me).

    Thanks for sharing the code and your experience.

    Reply

  3. Alexey on October 24, 2006 11:21 am

    Thanks for the code! :) I was looking for simple curl/C++ example, and couldn’t find one.
    BTW, spaces between <’s after cout prevent compilation (so simple copy-paste doesn’t work).

    Reply

    Luckyspin reply on November 29th, 2006 9:00 pm:

    Yeah, it’s weird. I’ve tried deleting them but everytime I save the post, WP seems to add them back. Grr!

    Reply

  4. Prashant on January 13, 2007 1:09 am

    Simple, perfect and to the point
    thanks for the sample code
    it really help me to download the urls
    thanks again

    Reply

    sai reply on October 30th, 2008 9:49 pm:

    Error: [7] - couldn’t connect to host error occurs while running the program.
    can u tell me how to compile this code and run.

    thanks

    Reply

  5. Ivan on February 11, 2007 6:14 am

    Nice snippet ;-)
    But I would use stdio.h instead iostream…
    anyway, thx for the code =))

    Reply

  6. Simon on February 16, 2007 11:40 am

    Thanks for the code snippet, invaluable!

    Reply

  7. Hmail on March 4, 2007 5:52 am

    Thank you very, very much for this little script. I was screwing around with libcurl, and couldn’t figure out why it didn’t work. But with your script as reference, I can easily fetch a page, login to a forum and so on.

    Thank you very much!

    Reply

    Ben reply on June 23rd, 2008 8:54 am:

    Hi Hamil,
    Hope you are doing wonderful. I have just started learning libcurl and I am trying to login to a website. Would you like to share me with the piece of code, that does the logging. Thank you for posting your comments and the success adventure with libcurl.

    Have a wonderful day !
    -Biranchi

    Reply

  8. fjordan on April 11, 2007 9:45 am

    Well, a neat but a little bit incomplete tutorial, from the official site you could find:

    http://curl.haxx.se/libcurl/c/libcurl-tutorial.html

    where you may get more comprehensive info from compliation/linking and code snippets…

    cheers

    Reply

    Luckyspin reply on April 23rd, 2007 7:26 pm:

    Yeah I know the docs are all there, but when I went looking I couldn’t find a simple example to just get me started. Hence this little snippet. Apparently it’s been useful to a few people so that’s cool =)

    Reply

  9. Mark on April 22, 2007 11:50 am

    Yes, I agree with everyone. This explanation and code snippet is very very helpful to me! Yes, fjordan, there is the detailed libcurl tutorial, but this snippet gets you started fast, then you can refer to the tutorial as a next step. Thanks Todd!

    Reply

  10. didi on April 22, 2007 12:09 pm

    Brilliant thank you. I was looking for this the whole night

    Reply

  11. bronco on August 10, 2007 1:28 pm

    could it be that I must free or clean the buffer? i try to us this in a class an my ram grows all the time?

    Thx for this cool example!!

    Reply

  12. Felton on August 23, 2007 1:52 pm

    Thanks for this. It really helped me out!

    Reply

  13. alex on August 26, 2007 2:12 am

    Hi! I’am from Poland, sorry in my language. :(
    How to uploading files / images in cURL ?
    Please any example… plisse

    Thanks You Very Much!!!

    Reply

  14. Larry_Croft on August 27, 2007 12:04 am

    Thanks for that snippet - you just saved me a lot of time reading the docs.

    Reply

  15. kinglaft on September 30, 2007 9:26 pm

    Thanks, sometime I also want to use java to realize your idea.

    http://www.greatnotebook.com/libcurl.html

    Reply

  16. d on October 1, 2007 5:31 pm

    Thanks for this. I too was having some problems getting a string buffer in C++ filled from the callbacks in libcurl. Cheers!

    Reply

  17. abuelochipo on November 9, 2007 8:58 am

    Thanks a lot!! a very useful code!!

    Reply

  18. Fabio on April 17, 2008 4:14 am

    Thank you!
    Great code!

    It will be nice if you have a snippet like this for using SSL with libcurl!
    Please let me know if you have

    Reply

    Luckyspin reply on April 27th, 2008 7:52 pm:

    I haven’t ever tried it with SSL I’m afraid. If you do, let me know how you did it. Thanks!

    Reply

  19. Unexpected popularity with C++ | Luckyspin.org on May 24, 2008 2:59 pm

    [...] course, I could be writing about the Twitter outages, but why follow the sheep? ;)] Take my post on using libcurl with C++. This was something that I threw out there a couple of years ago as a result of a small project on [...]

  20. Austin K on June 13, 2008 7:35 am

    Thanks. I was looking for a simple libcurl example to do just this. I’ll be sure to check out your other posts.

    Reply

    Luckyspin reply on June 13th, 2008 3:09 pm:

    Hey, no worries. Glad it was useful. What did you end up doing with it?

    Reply

    Austin K reply on June 14th, 2008 6:35 am:

    I was bored and thought about writing a quick C++ app that could pull stock quotes from the Internet. I found out that Yahoo offers CSV files of stock market data so I just needed a way to pull them off their website. I thought about writing my own HTTP parser, but then I discovered curl, libcurl, and this example.

    Reply

  21. Ben on June 19, 2008 2:29 pm

    Thanks for the code, I got to get it running immediately just after a minor modification. Now I want to do a log in to a web page. From one website I came to know in php I can use curl_exec and curl_getinfo to pass the post data information.

    I also want to get a particular xml file from the website and then modify it and send it back to the website.

    If anyone has done similar things before, your advice will be highly appreciated.

    -Biranchi

    Reply

  22. Tomy on June 28, 2008 11:18 pm

    I was trying to find some simple curl/C++ examples, but couldn’t find any. This code snippet is invaluable! Thanks again! :)

    Cheers from Latvia :)

    Reply

  23. Aaron on July 3, 2008 2:30 pm

    Hey!

    I’ve got some code which is 95% of what you have here, and the rest is just appending a file extension to the file name, then saving the recieved data to file, rather than sending to to std:cout. It works perfectly when directed to html documents, but trying to open other types (I’ve tried doc and pdf), it seems the file ends up partially corrupted. The size seems to match, but it’s just generally unreadable.

    What is strange is that by enabling CURLOPT_VERBOSE, I see that the connection feedback does seem to be correctly interpreting the content type.

    Is there something futher needed to be done for non-html documents?

    Reply

    Luckyspin reply on July 4th, 2008 7:30 am:

    That’s a good question. I’m not exactly sure to be honest. Perhaps there is a different curl option that needs to be set? Also, what happens if you do a diff between the file you downloaded using your program and the original binary file?

    Reply

    Aaron reply on July 4th, 2008 12:45 pm:

    Hey never mind any of that, I figured it out. I needed to open the file stream with (ios::binary | ios::out) because certain bitpatterns would prematurely terminate the operation, for this particular use =)

    Reply

    Luckyspin reply on July 4th, 2008 12:49 pm:

    That’s good to know!

  24. Aaron on July 4, 2008 11:17 am

    Oh, I should explain… the parameter passed to the program only determines the file name at the moment. The actual URL is constant and is just a random pdf from the internet

    Reply

  25. Eric on August 13, 2008 10:26 pm

    You, sir, are a libcurl legend. How much do we owe you for this awesomeness?

    Reply

    Luckyspin reply on August 15th, 2008 8:13 am:

    As I’ve said before there is no charge for awesomeness!

    Reply

  26. StickNews on October 15, 2008 4:45 am

    Great! Thanks! Now I exactly rewriting my RSS parser for site on C++, since I nube in Linux this code is great example what I must do… One question: how can I put to request needed headers like User-Agent and so on?

    Reply

  27. Nick on December 3, 2008 3:44 pm

    Hello!

    I’m writing a webcrawler that will save an html file from an input url and I want to use libcurl. I downloaded the zip file for the library and now I’m not sure what to do to make it work in NetBeans IDE. If you could help it would be GREATLY appreciated. Also, your sample code provides a great example for using the library! Thanks!!

    Reply

    Luckyspin reply on December 6th, 2008 2:09 pm:

    To be honest I don’t know much about the specifics of Netbeans. However, I imagine it’s the same as any other IDE. Create a project, import the files, setup a compiler, away you go. No doubt there are plenty of tutorials in the Netbeans help or from their community. Good luck!

    Reply

    Nick reply on December 24th, 2008 12:04 pm:

    Hi again,

    I’ve been trying to get this to work for a long time to no avail, I still get build errors:

    g++.exe -c -g -o build/Debug/Cygwin-Windows/webText.o webText.cpp
    webText.cpp:3:21: curl.h: No such file or directory
    webText.cpp:8: error: `CURL_ERROR_SIZE’ was not declared in this scope
    webText.cpp: In function `void usage()’:
    webText.cpp:36: error: expected primary-expression before ‘<’ token
    webText.cpp:36: error: invalid operands of types `const char[12]‘ and `’ to binary `operator<<’
    webText.cpp: In function `int main(int, char**)’:
    webText.cpp:49: error: expected primary-expression before ‘<’ token
    webText.cpp:49: error: no match for ‘operator<<’ in ‘”Retrieving ” << url’
    webText.cpp:52: error: `CURL’ undeclared (first use this function)
    webText.cpp:52: error: (Each undeclared identifier is reported only once for each function it appears in.)
    webText.cpp:52: error: `curl’ undeclared (first use this function)
    webText.cpp:53: error: `CURLcode’ undeclared (first use this function)
    webText.cpp:53: error: expected `;’ before “result”
    webText.cpp:56: error: `curl_easy_init’ undeclared (first use this function)
    webText.cpp:61: error: `CURLOPT_ERRORBUFFER’ undeclared (first use this function)
    webText.cpp:61: error: `errorBuffer’ undeclared (first use this function)
    webText.cpp:61: error: `curl_easy_setopt’ undeclared (first use this function)
    webText.cpp:62: error: `CURLOPT_URL’ undeclared (first use this function)
    webText.cpp:63: error: `CURLOPT_HEADER’ undeclared (first use this function)
    webText.cpp:64: error: `CURLOPT_FOLLOWLOCATION’ undeclared (first use this function)
    webText.cpp:65: error: `CURLOPT_WRITEFUNCTION’ undeclared (first use this function)
    webText.cpp:66: error: `CURLOPT_WRITEDATA’ undeclared (first use this function)
    webText.cpp:69: error: `result’ undeclared (first use this function)
    webText.cpp:69: error: `curl_easy_perform’ undeclared (first use this function)
    webText.cpp:72: error: `curl_easy_cleanup’ undeclared (first use this function)
    webText.cpp:75: error: `CURL_OK’ undeclared (first use this function)
    webText.cpp:86: error: expected `}’ at end of input
    make[1]: *** [build/Debug/Cygwin-Windows/webText.o] Error 1

    I apologize for the length of the message but I was wondering if you could deduce a solution based on this. When you downloaded the library did you put it in a specific directory?

    Thank you very much once again! Happy Holidays!

    Reply

    Luckyspin reply on January 6th, 2009 9:00 am:

    The compile warning is telling you that you have not reference the include files correctly in your setup. You need to download the libcurl source and set up your project to point to the .h files.

  28. mike on March 29, 2009 4:56 pm

    hey,

    cool article, but i have 1 problem with your code (and really any time i try to use libcurl. i’ve downloaded this: http://curl.haxx.se/latest.cgi?curl=win32-ssl-devel-msvc

    (the msvc libcurl download) but when i run your exact code, i get linker errors. I’ve included the “includes/” directory which contain all .h files, but the linker error is coming back with something about unresolved external symbols. this obviously means these 4 symbols aren’t defined anywhere, but they’re in easy.h.

    here are the errors:

    Error1error LNK2019: unresolved external symbol __imp__curl_easy_cleanup referenced in function _maincurl-test.obj

    Error2error LNK2019: unresolved external symbol __imp__curl_easy_perform referenced in function _maincurl-test.obj

    Error3error LNK2019: unresolved external symbol __imp__curl_easy_setopt referenced in function _maincurl-test.obj

    Error4error LNK2019: unresolved external symbol __imp__curl_easy_init referenced in function _maincurl-test.obj

    any assistance would be greatly appreciated.

    Reply

    Luckyspin reply on April 20th, 2009 8:38 am:

    I’m afraid I don’t know what might be causing the error. It’s obviously something to do with your environment but I can’t guess at what from here. Try posting the problem to the libcurl list or forums.

    Reply

    Alon Diamant reply on June 23rd, 2009 1:53 am:

    You forgot linking against the cURL .lib file. :)

    Reply

  29. Martin on April 25, 2009 11:56 pm

    Mike - I got the same linker errors when trying to link against the static lib (curllib_static.lib). Switch to the dll (curllib.lib) and it should be ok. Although of course you will need to have curllib.dll on your path (along with any other dependencies like ssleay32.dll etc which you can get from the libcurl root folder).

    Reply

  30. Bo Frederiksen on May 4, 2009 6:14 am

    Doesn’t ‘exit()’ require the ‘process’ library?

    Reply

  31. Jesse on June 11, 2009 3:59 pm

    @mike
    you need to set an additional library up in this case the libcurl.lib file that should come from the package you downloaded. Set the linker path to that and you should be good. Whenever I run it though, I get “program_name” is forced to close error and I’m stuck. I get no errors, not even warnings and I try to log in via a post request. Any idea you guys?

    Reply

    Luckyspin reply on June 14th, 2009 5:27 pm:

    Not entirely sure what would be causing that error. Have you tried stepping through your code in a debugger? Do you know exactly where it fails?

    Reply

  32. amado martinez on July 1, 2009 8:41 am

    thank you very much for this!! I’ve converted your code into a static class, making the code more portable.
    It’s available on my site.

    http://projectivemotion.com/?p=41

    Reply

原创粉丝点击