llcurl.h

Go to the documentation of this file.
00001 
00034 #ifndef LL_LLCURL_H
00035 #define LL_LLCURL_H
00036 
00037 #include "linden_common.h"
00038 
00039 #include <sstream>
00040 #include <string>
00041 #include <vector>
00042 
00043 #include <boost/intrusive_ptr.hpp>
00044 #include <curl/curl.h> // TODO: remove dependency
00045 
00046 #include "llbuffer.h"
00047 #include "lliopipe.h"
00048 #include "llsd.h"
00049 
00050 class LLMutex;
00051 
00052 // For whatever reason, this is not typedef'd in curl.h
00053 typedef size_t (*curl_header_callback)(void *ptr, size_t size, size_t nmemb, void *stream);
00054 
00055 class LLCurl
00056 {
00057         LOG_CLASS(LLCurl);
00058         
00059 public:
00060         class Easy;
00061         class Multi;
00062 
00063         struct TransferInfo
00064         {
00065                 TransferInfo() : mSizeDownload(0.0), mTotalTime(0.0), mSpeedDownload(0.0) {}
00066                 F64 mSizeDownload;
00067                 F64 mTotalTime;
00068                 F64 mSpeedDownload;
00069         };
00070         
00071         class Responder
00072         {
00073         //LOG_CLASS(Responder);
00074         public:
00075 
00076                 Responder();
00077                 virtual ~Responder();
00078 
00082                 static bool isGoodStatus(U32 status)
00083                 {
00084                         return((200 <= status) && (status < 300));
00085                 }
00086                 
00087                 virtual void error(U32 status, const std::string& reason);
00088                         // called with non-200 status codes
00089                 
00090                 virtual void result(const LLSD& content);
00091                 
00092                 // Override point for clients that may want to use this class when the response is some other format besides LLSD
00093                 virtual void completedRaw(U32 status, const std::string& reason,
00094                                                                   const LLChannelDescriptors& channels,
00095                                                                   const LLIOPipe::buffer_ptr_t& buffer);
00096 
00097                 virtual void completed(U32 status, const std::string& reason, const LLSD& content);
00104                         // Override to handle parsing of the header only.  Note: this is the only place where the contents
00105                         // of the header can be parsed.  In the ::completed call above only the body is contained in the LLSD.
00106                         virtual void completedHeader(U32 status, const std::string& reason, const LLSD& content);
00107 
00108         public: /* but not really -- don't touch this */
00109                 U32 mReferenceCount;
00110         };
00111         typedef boost::intrusive_ptr<Responder> ResponderPtr;
00112 
00113 
00117         static void setCAFile(const std::string& file);
00118 
00122         static void setCAPath(const std::string& path);
00123         
00127         static const std::string& getCAFile() { return sCAFile; }
00128 
00132         static const std::string& getCAPath() { return sCAPath; }
00133 
00137         static void initClass();
00138 
00142         static void cleanupClass();
00143 
00147         static std::string strerror(CURLcode errorcode);
00148         
00149         // For OpenSSL callbacks
00150         static std::vector<LLMutex*> sSSLMutex;
00151 
00152         // OpenSSL callbacks
00153         static void ssl_locking_callback(int mode, int type, const char *file, int line);
00154         static unsigned long ssl_thread_id(void);
00155 
00156 private:
00157         static std::string sCAPath;
00158         static std::string sCAFile;
00159 };
00160 
00161 namespace boost
00162 {
00163         void intrusive_ptr_add_ref(LLCurl::Responder* p);
00164         void intrusive_ptr_release(LLCurl::Responder* p);
00165 };
00166 
00167 
00168 class LLCurlRequest
00169 {
00170 public:
00171         LLCurlRequest();
00172         ~LLCurlRequest();
00173 
00174         void get(const std::string& url, LLCurl::ResponderPtr responder);
00175         bool getByteRange(const std::string& url, S32 offset, S32 length, LLCurl::ResponderPtr responder);
00176         bool post(const std::string& url, const LLSD& data, LLCurl::ResponderPtr responder);
00177         S32  process();
00178         S32  getQueued();
00179 
00180 private:
00181         void addMulti();
00182         LLCurl::Easy* allocEasy();
00183         bool addEasy(LLCurl::Easy* easy);
00184         
00185 private:
00186         typedef std::set<LLCurl::Multi*> curlmulti_set_t;
00187         curlmulti_set_t mMultiSet;
00188         LLCurl::Multi* mActiveMulti;
00189         S32 mActiveRequestCount;
00190 };
00191 
00192 class LLCurlEasyRequest
00193 {
00194 public:
00195         LLCurlEasyRequest();
00196         ~LLCurlEasyRequest();
00197         void setopt(CURLoption option, S32 value);
00198         void setoptString(CURLoption option, const std::string& value);
00199         void setPost(char* postdata, S32 size);
00200         void setHeaderCallback(curl_header_callback callback, void* userdata);
00201         void setWriteCallback(curl_write_callback callback, void* userdata);
00202         void setReadCallback(curl_read_callback callback, void* userdata);
00203         void slist_append(const char* str);
00204         void sendRequest(const std::string& url);
00205         void requestComplete();
00206         S32 perform();
00207         bool getResult(CURLcode* result, LLCurl::TransferInfo* info = NULL);
00208         std::string getErrorString();
00209 
00210 private:
00211         CURLMsg* info_read(S32* queue, LLCurl::TransferInfo* info);
00212         
00213 private:
00214         LLCurl::Multi* mMulti;
00215         LLCurl::Easy* mEasy;
00216         bool mRequestSent;
00217         bool mResultReturned;
00218 };
00219 
00220 #endif // LL_LLCURL_H

Generated on Fri May 16 08:32:23 2008 for SecondLife by  doxygen 1.5.5