cURL
Haxx ad
libcurl

curl's project page on SourceForge.net

Sponsors:
Haxx

cURL > Mailing List > Monthly Index > Single Mail

curlpp mailing list Archives

[cURLpp] getInfo and cookie interface patches for cURLpp-0.5.2

From: Peteris Krumins [Newsgroups] <pknewsgroups_at_gmail.com>
Date: Mon, 01 Aug 2005 14:19:05 +0300

 Hello!

 Here are two patches for curlpp-0.5.2.
 The first includes simple getInfo interface to get internal information
about curl handle via
 curl_easy_getinfo(3) call. It also adds iterator capability to SList
which was missing and
 it fixes a bug where std::runtime_error could be thrown instead of
cURLpp::RuntimeError.
 Also includes example06 which shows how to use the getInfo interface.
 Patch your curlpp-0.5.2 with curlpp.01of02.patch file.

 The second patch includes simple cookie interface which has already
went into curl's CVS
 and will be available in the next release of curl (or you can get CVS
version).
 Those who want to use this interface will have to take patch from my
page http://www.catonmat.net
 and apply it on curl-7.14.0. When you have done it, apply
curlpp.02of02.patch on top of curlpp.01.of02.patch,
 which will add an option CookieList and create and example07 which
shows cookie interface usage
 and even includes a simple parser for creating data structure out of
Netscape formatted string which
 is returned by the interface.

 Both patches are also available on my page http://www.catonmat.net

--
P.Krumins
If you or your company found this patch useful and it saved you some 
hours of work you might want to buy me a gift!
Look at my wishlist:
http://www.amazon.co.uk/exec/obidos/registry/3LQJRP8M89NE6

Index: curlpp/Options.hpp
===================================================================
--- curlpp/Options.hpp (.../curlpp-getInfo) (revision 60)
+++ curlpp/Options.hpp (.../curlpp-getInfo-cookie-interface) (revision 60)
@@ -30,6 +30,11 @@
   namespace Options
   {
     /**
+ * Cookie interface.
+ */
+ typedef cURLpp::OptionTrait< std::string, cURL::CURLOPT_COOKIELIST > CookieList;
+
+ /**
      * Behavior options.
      */
     typedef cURLpp::OptionTrait< bool, cURL::CURLOPT_VERBOSE > Verbose;
Index: examples/example07.cpp
===================================================================
--- examples/example07.cpp (.../curlpp-getInfo) (revision 0)
+++ examples/example07.cpp (.../curlpp-getInfo-cookie-interface) (revision 60)
@@ -0,0 +1,158 @@
+#include <string>
+#include <cstdlib>
+#include <sstream>
+#include <vector>
+#include <iostream>
+#include <ctime>
+
+#include <curlpp/cURLpp.hpp>
+#include <curlpp/Options.hpp>
+
+using namespace cURLpp;
+
+class YesNo {
+public:
+ explicit YesNo(bool yn) : yesno(yn) {}
+ std::string operator()() const {
+ return yesno ? "Yes" : "No";
+ }
+ friend std::ostream &operator<<(std::ostream &strm, const YesNo &yn) {
+ strm << yn();
+ return strm;
+ }
+private:
+ bool yesno;
+};
+
+struct Cookie {
+ std::string name;
+ std::string value;
+ std::string domain;
+ std::string path;
+ std::time_t expires;
+ bool tail;
+ bool secure;
+};
+
+std::ostream &
+operator<<(std::ostream &strm, const Cookie &cook)
+{
+ strm << "Cookie: '" << cook.name << "' (secure: " << YesNo(cook.secure) << ", tail: "
+ << YesNo(cook.tail) << ") for domain: '" << cook.domain << "', "
+ << "path: '" << cook.path << "'.\n";
+ strm << "Value: '" << cook.value << "'.\n";
+ strm << "Expires: '" << std::ctime(&cook.expires) << "'.\n";
+
+ return strm;
+}
+
+std::vector<std::string> &
+split_cookie_str(const std::string &str, std::vector<std::string> &in)
+{
+ std::string part;
+
+ std::istringstream strm(str);
+ while (std::getline(strm, part, '\t'))
+ in.push_back(part);
+
+ return in;
+}
+
+std::vector<std::string>
+splitCookieStr(const std::string &str)
+{
+ std::vector<std::string> split;
+ split_cookie_str(str, split);
+ return split;
+}
+
+std::vector<std::string> &
+splitCookieStr(const std::string &str, std::vector<std::string> &in)
+{
+ return split_cookie_str(str, in);
+}
+
+int StrToInt(const std::string &str)
+{
+ std::istringstream strm(str);
+ int i = 0;
+ if (!(strm >> i)) {
+ throw cURLpp::RuntimeError("Unable to convert string '" + str + "' to integer!");
+ }
+ return i;
+}
+
+Cookie
+MakeCookie(const std::string &str_cookie)
+{
+ std::vector<std::string> vC = splitCookieStr(str_cookie);
+ Cookie cook;
+
+ cook.domain = vC[0];
+ cook.tail = vC[1] == "TRUE";
+ cook.path = vC[2];
+ cook.secure = vC[3] == "TRUE";
+ cook.expires = StrToInt(vC[4]);
+ cook.name = vC[5];
+ cook.value = vC[6];
+
+ return cook;
+}
+
+int
+main(void)
+{
+ try {
+ Cleanup myCleanup;
+ Easy exEasy;
+ std::vector<std::string> cookieList;
+
+ // a cookie as in HTTP header
+ cookieList.push_back("Set-Cookie: GMAIL_AT=EXPIRED;expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com");
+
+ // a Netscape style cookie with \t
+ cookieList.push_back(".google.com\tTRUE\t/\tFALSE\t2147483647\tLSID\tI like you GOOGLE");
+
+ // a Netscape style cookie with tabs in string
+ cookieList.push_back(".yahoo.com TRUE / FALSE 0 YAHOO_COOKIE I like you yahoo, too");
+
+ exEasy.setOpt(new Options::Url("http://www.google.com"));
+ exEasy.setOpt(new Options::FileTime(true));
+ exEasy.setOpt(new Options::Verbose(true));
+
+ // loop throught the cookies and add one by one
+ //
+ for (std::vector<std::string>::iterator it = cookieList.begin();
+ it != cookieList.end();
+ ++it)
+ {
+ exEasy.setOpt(Options::CookieList(*it));
+ }
+ exEasy.perform();
+
+ // see what cookies we got
+ //
+ std::cout << "\nCookies from cookie engine:" << std::endl;
+ SList Cookies;
+ exEasy.getInfo(cURL::CURLINFO_COOKIELIST, Cookies);
+ int i = 1;
+ for (SList::const_iterator it = Cookies.begin();
+ it != Cookies.end();
+ ++it, i++)
+ {
+ std::cout << "[" << i << "]: " << MakeCookie(*it) << std::endl;
+ }
+
+ std::exit(EXIT_SUCCESS);
+ }
+ catch(cURLpp::RuntimeError &e)
+ {
+ std::cerr << e.what() << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ catch(cURLpp::LogicError &e)
+ {
+ std::cout << e.what() << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+}
Index: examples/Makefile.am
===================================================================
--- examples/Makefile.am (.../curlpp-getInfo) (revision 60)
+++ examples/Makefile.am (.../curlpp-getInfo-cookie-interface) (revision 60)
@@ -2,7 +2,7 @@
 maintener_programs = example04
 endif
 
-noinst_PROGRAMS = example01 example02 example03 example05 example06 ${maintener_programs}
+noinst_PROGRAMS = example01 example02 example03 example05 example06 example07 ${maintener_programs}
 
 
 
@@ -16,6 +16,8 @@
 
 example06_SOURCES = example06.cpp
 
+example07_SOURCES = example07.cpp
+
 if MAINTENER_CODE
 example04_SOURCES = example04.cpp
 endif
Index: examples/README
===================================================================
--- examples/README (.../curlpp-getInfo) (revision 60)
+++ examples/README (.../curlpp-getInfo-cookie-interface) (revision 60)
@@ -4,6 +4,8 @@
  Example 2: an upload example.
  Example 3: verbose callback example.
  Example 6: getInfo example.
+ Example 7: cookie intercafe example via getInfo.
+ Demonstrates usage of SList which example06 did not.
 
 Examples below are only temporary. You should not rely
 on their particuliar use.

Index: curlpp/SList.cpp
===================================================================
--- curlpp/SList.cpp (.../curlpp-0.5.2) (revision 60)
+++ curlpp/SList.cpp (.../branches/curlpp-getInfo) (revision 60)
@@ -31,14 +25,25 @@
 
 cURLpp::SList::~SList()
 {
- if( mList != 0 )
- {
+ slist_clear();
+}
+
+void
+cURLpp::SList::clear()
+{
+ slist_clear();
+ mData.clear();
+}
+
+void
+cURLpp::SList::slist_clear()
+{
+ if( mList != 0 ) {
       curl_slist_free_all( mList );
       mList = 0;
    }
 }
 
-
 void
 cURLpp::SList::set( const std::list< std::string > &list)
 {
@@ -80,6 +85,19 @@
   return (*this);
 }
 
+cURLpp::SList &
+cURLpp::SList::operator=(cURL::curl_slist &list)
+{
+ cURL::curl_slist *tr = &list;
+ while (tr) {
+ mData.push_back(tr->data);
+ tr = tr->next;
+ }
+ mList = &list;
+ return *this;
+}
+
+
 cURL::curl_slist *
 cURLpp::SList::cslist() const
 {
Index: curlpp/Easy.cpp
===================================================================
--- curlpp/Easy.cpp (.../curlpp-0.5.2) (revision 60)
+++ curlpp/Easy.cpp (.../branches/curlpp-getInfo) (revision 60)
@@ -23,10 +23,11 @@
 
 #include "config.h"
 #include "Easy.hpp"
+#include "SList.hpp"
 
 cURLpp::Easy::Easy()
 {}
-
+
 cURLpp::Easy::~Easy()
 {}
 
@@ -61,4 +62,36 @@
     OptionList::setOpt(options);
 }
 
+template <class T>
+void
+cURLpp::Easy::getInfo(const cURL::CURLINFO &option, T &val)
+{
+ cURL::CURLcode code;
+
+ code = cURL::curl_easy_getinfo(myCurl.getHandle(), option, &val);
+ if ( code != cURL::CURLE_OK ) {
+ throw cURLpp::LibcurlRuntimeError( myCurl.getErrorBuffer(), code );
+ }
+}
 
+template <>
+void
+cURLpp::Easy::getInfo<cURLpp::SList>(const cURL::CURLINFO &option, cURLpp::SList &val)
+{
+ cURL::CURLcode code;
+ cURL::curl_slist *cookieList;
+
+ code = cURL::curl_easy_getinfo(myCurl.getHandle(), option, &cookieList);
+ if ( code != cURL::CURLE_OK ) {
+ throw cURLpp::LibcurlRuntimeError( myCurl.getErrorBuffer(), code );
+ }
+
+ val = *cookieList;
+}
+
+// explicitly instantiate for char *, long, double
+// these and SList are the only types to be used with getInfo
+//
+template void cURLpp::Easy::getInfo<char *>(const cURL::CURLINFO &option, char * &val);
+template void cURLpp::Easy::getInfo<long>(const cURL::CURLINFO &option, long &val);
+template void cURLpp::Easy::getInfo<double>(const cURL::CURLINFO &option, double &val);
Index: curlpp/SList.hpp
===================================================================
--- curlpp/SList.hpp (.../curlpp-0.5.2) (revision 60)
+++ curlpp/SList.hpp (.../branches/curlpp-getInfo) (revision 60)
@@ -43,13 +43,26 @@
     ~SList();
 
     SList &operator=(const std::list< std::string > &list);
+ SList &operator=(cURL::curl_slist &list);
     operator std::list< std::string > ();
 
+ typedef std::list< std::string >::iterator iterator;
+ typedef std::list< std::string >::const_iterator const_iterator;
+ typedef std::list< std::string >::size_type size_type;
+
+ iterator begin() { return mData.begin(); }
+ iterator end() { return mData.end(); }
+ const_iterator begin() const { return mData.begin(); }
+ const_iterator end() const { return mData.end(); }
+ size_type size() { return mData.size(); }
+ void clear();
+
     cURL::curl_slist *cslist() const;
     std::list< std::string > list();
 
   private:
     void set(const std::list< std::string > &list);
+ void slist_clear();
     void update();
      
     cURL::curl_slist *mList;
Index: curlpp/cURLpp.cpp
===================================================================
--- curlpp/cURLpp.cpp (.../curlpp-0.5.2) (revision 60)
+++ curlpp/cURLpp.cpp (.../branches/curlpp-getInfo) (revision 60)
@@ -32,7 +32,7 @@
    std::string buffer;
    char* p = cURL::curl_escape(url.c_str(), url.size());
    if(!p) {
- throw std::runtime_error( "unable to escape the string" ); //we got an error
+ throw RuntimeError( "unable to escape the string" );
    }
    else {
      buffer = p;
@@ -48,7 +48,7 @@
    char* p = cURL::curl_unescape( url.c_str(), url.size() );
    if ( !p )
    {
- throw RuntimeError( "unable to escape the string" ); //we got an error
+ throw RuntimeError( "unable to unescape the string" );
    }
    else
    {
@@ -65,7 +65,7 @@
    char* p = cURL::curl_getenv( name.c_str() );
    if ( !p )
    {
- throw RuntimeError( "unable to get the environnement string" ); //we got an error
+ throw RuntimeError( "unable to get the environnement string" );
    }
    else
    {
@@ -81,7 +81,7 @@
   char* p = cURL::curl_version();
    if ( !p )
    {
- throw RuntimeError( "unable to get the libcurl version" ); //we got an error
+ throw RuntimeError( "unable to get the libcurl version" );
    }
       
    return std::string( p );
Index: curlpp/Easy.hpp
===================================================================
--- curlpp/Easy.hpp (.../curlpp-0.5.2) (revision 60)
+++ curlpp/Easy.hpp (.../branches/curlpp-getInfo) (revision 60)
@@ -71,6 +71,12 @@
      */
     cURL::CURL *getHandle();
 
+ /**
+ * This function returns internal information from cURL handle.
+ */
+ template <class T>
+ void getInfo(const cURL::CURLINFO &option, T &val);
+
   private:
     cURLpp::CurlHandle myCurl;
   };
Index: curlpp/CurlHandle.cpp
===================================================================
--- curlpp/CurlHandle.cpp (.../curlpp-0.5.2) (revision 60)
+++ curlpp/CurlHandle.cpp (.../branches/curlpp-getInfo) (revision 60)
@@ -62,7 +62,3 @@
 {
   option( cURL::CURLOPT_ERRORBUFFER, (void *)buffer);
 }
-
-
-
-
Index: curlpp/CurlHandle.hpp
===================================================================
--- curlpp/CurlHandle.hpp (.../curlpp-0.5.2) (revision 60)
+++ curlpp/CurlHandle.hpp (.../branches/curlpp-getInfo) (revision 60)
@@ -61,6 +61,11 @@
      */
     cURL::CURL * CURLPPAPI getHandle();
 
+ /**
+ * This function returns a pointer to error buffer
+ */
+ char *getErrorBuffer() { return mErrorBuffer; }
+
   private:
     CURLPPAPI CurlHandle(const CurlHandle &other);
     CURLPPAPI CurlHandle& operator=(const CurlHandle &other);
Index: examples/example06.cpp
===================================================================
--- examples/example06.cpp (.../curlpp-0.5.2) (revision 0)
+++ examples/example06.cpp (.../branches/curlpp-getInfo) (revision 60)
@@ -0,0 +1,62 @@
+#include <string>
+#include <stdlib.h>
+#include <ctime>
+
+#include <curlpp/cURLpp.hpp>
+#include <curlpp/Options.hpp>
+
+using namespace cURLpp;
+
+int
+main(void)
+{
+ try {
+ Cleanup myCleanup;
+ Easy exEasy;
+
+ exEasy.setOpt(new Options::Url("http://www.google.com"));
+ exEasy.setOpt(new Options::FileTime(true));
+ exEasy.perform();
+
+ // four types that can be used with getInfo()
+ //
+ char *charType;
+ long longType;
+ double doubleType;
+ SList SListType;
+
+ // the 1st parameter of getInfo method is cURL::CURLINFO_* constant
+ // (see http://curl.haxx.se/libcurl/c/curl_easy_getinfo.html for a list of constants)
+ // the 2nd parameter is type mentioned in the same page
+ //
+ exEasy.getInfo(cURL::CURLINFO_EFFECTIVE_URL, charType);
+ std::cout << "---------------\n";
+ std::cout << "Last used url: " << charType << std::endl;
+
+ exEasy.getInfo(cURL::CURLINFO_RESPONSE_CODE, longType);
+ std::cout << "Last respone code: " << longType << std::endl;
+
+ exEasy.getInfo(cURL::CURLINFO_FILETIME, longType);
+ if (longType == -1) {
+ std::cout << "Server did not return remote time" << std::endl;
+ }
+ else {
+ std::cout << "Remote time of retrieved document: " << std::ctime(static_cast<std::time_t *>(&longType))
+ << std::endl;
+ }
+ exEasy.getInfo(cURL::CURLINFO_SPEED_DOWNLOAD, doubleType);
+ std::cout << "Average d/l speed: " << doubleType << " bytes/sec" << std::endl;
+
+ std::exit(EXIT_SUCCESS);
+ }
+ catch(cURLpp::RuntimeError &e)
+ {
+ std::cerr << e.what() << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ catch(cURLpp::LogicError &e)
+ {
+ std::cout << e.what() << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+}
\ No newline at end of file
Index: examples/Makefile.am
===================================================================
--- examples/Makefile.am (.../curlpp-0.5.2) (revision 60)
+++ examples/Makefile.am (.../branches/curlpp-getInfo) (revision 60)
@@ -2,7 +2,7 @@
 maintener_programs = example04
 endif
 
-noinst_PROGRAMS = example01 example02 example03 example05 ${maintener_programs}
+noinst_PROGRAMS = example01 example02 example03 example05 example06 ${maintener_programs}
 
 
 
@@ -14,6 +14,7 @@
 
 example05_SOURCES = example05.cpp
 
+example06_SOURCES = example06.cpp
 
 if MAINTENER_CODE
 example04_SOURCES = example04.cpp
Index: examples/README
===================================================================
--- examples/README (.../curlpp-0.5.2) (revision 60)
+++ examples/README (.../branches/curlpp-getInfo) (revision 60)
@@ -3,6 +3,7 @@
  Example 1: This example is made to show you how you can use the Options.
  Example 2: an upload example.
  Example 3: verbose callback example.
+ Example 6: getInfo example.
 
 Examples below are only temporary. You should not rely
 on their particuliar use.

_______________________________________________
cURLpp mailing list
cURLpp_at_rrette.com
http://www.rrette.com/mailman/listinfo/curlpp
Received on 2005-08-01

These mail archives are generated by hypermail.

donate! Page updated November 12, 2010.
web site info

File upload with ASP.NET