diff options
author | Jacek Antonelli | 2008-08-15 23:45:34 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:34 -0500 |
commit | cd17687f01420952712a500107e0f93e7ab8d5f8 (patch) | |
tree | ce48c2b706f2c1176290e39fb555fbdf6648ce01 /linden/indra/llmessage/llcurl.h | |
parent | Second Life viewer sources 1.19.0.5 (diff) | |
download | meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.zip meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.gz meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.bz2 meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.xz |
Second Life viewer sources 1.19.1.0
Diffstat (limited to '')
-rw-r--r-- | linden/indra/llmessage/llcurl.h | 205 |
1 files changed, 142 insertions, 63 deletions
diff --git a/linden/indra/llmessage/llcurl.h b/linden/indra/llmessage/llcurl.h index 904bc64..3d9770b 100644 --- a/linden/indra/llmessage/llcurl.h +++ b/linden/indra/llmessage/llcurl.h | |||
@@ -1,8 +1,8 @@ | |||
1 | /** | 1 | /** |
2 | * @file llcurl.h | 2 | * @file llcurl.h |
3 | * @author Zero / Donovan | 3 | * @author Zero / Donovan |
4 | * @date 2006-10-15 | 4 | * @date 2006-10-15 |
5 | * @brief Curl wrapper | 5 | * @brief A wrapper around libcurl. |
6 | * | 6 | * |
7 | * $LicenseInfo:firstyear=2006&license=viewergpl$ | 7 | * $LicenseInfo:firstyear=2006&license=viewergpl$ |
8 | * | 8 | * |
@@ -41,104 +41,183 @@ | |||
41 | #include <vector> | 41 | #include <vector> |
42 | 42 | ||
43 | #include <boost/intrusive_ptr.hpp> | 43 | #include <boost/intrusive_ptr.hpp> |
44 | #include <curl/curl.h> | 44 | #include <curl/curl.h> // TODO: remove dependency |
45 | 45 | ||
46 | // #include "llhttpclient.h" | 46 | #include "llbuffer.h" |
47 | #include "lliopipe.h" | ||
48 | #include "llsd.h" | ||
49 | |||
50 | class LLMutex; | ||
51 | |||
52 | // For whatever reason, this is not typedef'd in curl.h | ||
53 | typedef size_t (*curl_header_callback)(void *ptr, size_t size, size_t nmemb, void *stream); | ||
47 | 54 | ||
48 | class LLCurl | 55 | class LLCurl |
49 | { | 56 | { |
57 | LOG_CLASS(LLCurl); | ||
58 | |||
50 | public: | 59 | public: |
60 | class Easy; | ||
51 | class Multi; | 61 | class Multi; |
52 | 62 | ||
63 | struct TransferInfo | ||
64 | { | ||
65 | TransferInfo() : mSizeDownload(0.0), mTotalTime(0.0), mSpeedDownload(0.0) {} | ||
66 | F64 mSizeDownload; | ||
67 | F64 mTotalTime; | ||
68 | F64 mSpeedDownload; | ||
69 | }; | ||
70 | |||
53 | class Responder | 71 | class Responder |
54 | { | 72 | { |
73 | //LOG_CLASS(Responder); | ||
55 | public: | 74 | public: |
75 | |||
56 | Responder(); | 76 | Responder(); |
57 | virtual ~Responder(); | 77 | virtual ~Responder(); |
58 | 78 | ||
59 | virtual void error(U32 status, const std::stringstream& content); // called with bad status codes | 79 | /** |
80 | * @brief return true if the status code indicates success. | ||
81 | */ | ||
82 | static bool isGoodStatus(U32 status) | ||
83 | { | ||
84 | return((200 <= status) && (status < 300)); | ||
85 | } | ||
86 | |||
87 | virtual void error(U32 status, const std::string& reason); | ||
88 | // called with non-200 status codes | ||
60 | 89 | ||
61 | virtual void result(const std::stringstream& content); | 90 | virtual void result(const LLSD& content); |
62 | 91 | ||
63 | virtual void completed(U32 status, const std::stringstream& content); | 92 | // Override point for clients that may want to use this class when the response is some other format besides LLSD |
93 | virtual void completedRaw(U32 status, const std::string& reason, | ||
94 | const LLChannelDescriptors& channels, | ||
95 | const LLIOPipe::buffer_ptr_t& buffer); | ||
96 | |||
97 | virtual void completed(U32 status, const std::string& reason, const LLSD& content); | ||
64 | /**< The default implemetnation calls | 98 | /**< The default implemetnation calls |
65 | either: | 99 | either: |
66 | * result(), or | 100 | * result(), or |
67 | * error() | 101 | * error() |
68 | */ | 102 | */ |
69 | 103 | ||
104 | // Override to handle parsing of the header only. Note: this is the only place where the contents | ||
105 | // of the header can be parsed. In the ::completed call above only the body is contained in the LLSD. | ||
106 | virtual void completedHeader(U32 status, const std::string& reason, const LLSD& content); | ||
107 | |||
70 | public: /* but not really -- don't touch this */ | 108 | public: /* but not really -- don't touch this */ |
71 | U32 mReferenceCount; | 109 | U32 mReferenceCount; |
72 | }; | 110 | }; |
73 | typedef boost::intrusive_ptr<Responder> ResponderPtr; | 111 | typedef boost::intrusive_ptr<Responder> ResponderPtr; |
74 | |||
75 | class Easy | ||
76 | { | ||
77 | public: | ||
78 | Easy(); | ||
79 | ~Easy(); | ||
80 | |||
81 | void get(const std::string& url, ResponderPtr); | ||
82 | void getByteRange(const std::string& url, S32 offset, S32 length, ResponderPtr); | ||
83 | |||
84 | void perform(); | ||
85 | 112 | ||
86 | private: | ||
87 | void prep(const std::string& url, ResponderPtr); | ||
88 | void report(CURLcode); | ||
89 | |||
90 | CURL* mHandle; | ||
91 | struct curl_slist* mHeaders; | ||
92 | |||
93 | std::string mURL; | ||
94 | std::string mRange; | ||
95 | std::stringstream mRequest; | ||
96 | 113 | ||
97 | std::stringstream mOutput; | 114 | /** |
98 | char mErrorBuffer[CURL_ERROR_SIZE]; | 115 | * @ brief Set certificate authority file used to verify HTTPS certs. |
99 | 116 | */ | |
100 | std::stringstream mHeaderOutput; // Debug | 117 | static void setCAFile(const std::string& file); |
101 | |||
102 | ResponderPtr mResponder; | ||
103 | |||
104 | friend class Multi; | ||
105 | }; | ||
106 | 118 | ||
119 | /** | ||
120 | * @ brief Set certificate authority path used to verify HTTPS certs. | ||
121 | */ | ||
122 | static void setCAPath(const std::string& path); | ||
123 | |||
124 | /** | ||
125 | * @ brief Get certificate authority file used to verify HTTPS certs. | ||
126 | */ | ||
127 | static const std::string& getCAFile() { return sCAFile; } | ||
128 | |||
129 | /** | ||
130 | * @ brief Get certificate authority path used to verify HTTPS certs. | ||
131 | */ | ||
132 | static const std::string& getCAPath() { return sCAPath; } | ||
133 | |||
134 | /** | ||
135 | * @ brief Initialize LLCurl class | ||
136 | */ | ||
137 | static void initClass(); | ||
138 | |||
139 | /** | ||
140 | * @ brief Cleanup LLCurl class | ||
141 | */ | ||
142 | static void cleanupClass(); | ||
143 | |||
144 | /** | ||
145 | * @ brief curl error code -> string | ||
146 | */ | ||
147 | static std::string strerror(CURLcode errorcode); | ||
148 | |||
149 | // For OpenSSL callbacks | ||
150 | static std::vector<LLMutex*> sSSLMutex; | ||
107 | 151 | ||
108 | class Multi | 152 | // OpenSSL callbacks |
109 | { | 153 | static void LLCurl::ssl_locking_callback(int mode, int type, const char *file, int line); |
110 | public: | 154 | static unsigned long LLCurl::ssl_thread_id(void); |
111 | Multi(); | 155 | |
112 | ~Multi(); | 156 | |
157 | |||
158 | private: | ||
113 | 159 | ||
114 | void get(const std::string& url, ResponderPtr); | 160 | static std::string sCAPath; |
115 | void getByteRange(const std::string& url, S32 offset, S32 length, ResponderPtr); | 161 | static std::string sCAFile; |
162 | }; | ||
116 | 163 | ||
117 | void process(); | 164 | namespace boost |
118 | 165 | { | |
119 | private: | 166 | void intrusive_ptr_add_ref(LLCurl::Responder* p); |
120 | Easy* easyAlloc(); | 167 | void intrusive_ptr_release(LLCurl::Responder* p); |
121 | void easyFree(Easy*); | 168 | }; |
122 | |||
123 | CURLM* mHandle; | ||
124 | |||
125 | typedef std::vector<Easy*> EasyList; | ||
126 | EasyList mFreeEasy; | ||
127 | }; | ||
128 | 169 | ||
129 | 170 | ||
130 | static void get(const std::string& url, ResponderPtr); | 171 | class LLCurlRequest |
131 | static void getByteRange(const std::string& url, S32 offset, S32 length, ResponderPtr responder); | 172 | { |
173 | public: | ||
174 | LLCurlRequest(); | ||
175 | ~LLCurlRequest(); | ||
176 | |||
177 | void get(const std::string& url, LLCurl::ResponderPtr responder); | ||
178 | bool getByteRange(const std::string& url, S32 offset, S32 length, LLCurl::ResponderPtr responder); | ||
179 | bool post(const std::string& url, const LLSD& data, LLCurl::ResponderPtr responder); | ||
180 | S32 process(); | ||
181 | S32 getQueued(); | ||
182 | |||
183 | private: | ||
184 | void addMulti(); | ||
185 | LLCurl::Easy* allocEasy(); | ||
186 | bool addEasy(LLCurl::Easy* easy); | ||
132 | 187 | ||
133 | static void initClass(); // *NOTE:Mani - not thread safe! | 188 | private: |
134 | static void process(); | 189 | typedef std::set<LLCurl::Multi*> curlmulti_set_t; |
135 | static void cleanup(); // *NOTE:Mani - not thread safe! | 190 | curlmulti_set_t mMultiSet; |
191 | LLCurl::Multi* mActiveMulti; | ||
192 | S32 mActiveRequestCount; | ||
136 | }; | 193 | }; |
137 | 194 | ||
138 | namespace boost | 195 | class LLCurlEasyRequest |
139 | { | 196 | { |
140 | void intrusive_ptr_add_ref(LLCurl::Responder* p); | 197 | public: |
141 | void intrusive_ptr_release(LLCurl::Responder* p); | 198 | LLCurlEasyRequest(); |
199 | ~LLCurlEasyRequest(); | ||
200 | void setopt(CURLoption option, S32 value); | ||
201 | void setoptString(CURLoption option, const std::string& value); | ||
202 | void setPost(char* postdata, S32 size); | ||
203 | void setHeaderCallback(curl_header_callback callback, void* userdata); | ||
204 | void setWriteCallback(curl_write_callback callback, void* userdata); | ||
205 | void setReadCallback(curl_read_callback callback, void* userdata); | ||
206 | void slist_append(const char* str); | ||
207 | void sendRequest(const std::string& url); | ||
208 | void requestComplete(); | ||
209 | S32 perform(); | ||
210 | bool getResult(CURLcode* result, LLCurl::TransferInfo* info = NULL); | ||
211 | std::string getErrorString(); | ||
212 | |||
213 | private: | ||
214 | CURLMsg* info_read(S32* queue, LLCurl::TransferInfo* info); | ||
215 | |||
216 | private: | ||
217 | LLCurl::Multi* mMulti; | ||
218 | LLCurl::Easy* mEasy; | ||
219 | bool mRequestSent; | ||
220 | bool mResultReturned; | ||
142 | }; | 221 | }; |
143 | 222 | ||
144 | #endif // LL_LLCURL_H | 223 | #endif // LL_LLCURL_H |