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>
00045
00046 #include "llbuffer.h"
00047 #include "lliopipe.h"
00048 #include "llsd.h"
00049
00050 class LLMutex;
00051
00052
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
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
00089
00090 virtual void result(const LLSD& content);
00091
00092
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
00105
00106 virtual void completedHeader(U32 status, const std::string& reason, const LLSD& content);
00107
00108 public:
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
00150 static std::vector<LLMutex*> sSSLMutex;
00151
00152
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