diff options
Diffstat (limited to 'linden/indra/llmessage/llhttpclient.cpp')
-rw-r--r-- | linden/indra/llmessage/llhttpclient.cpp | 157 |
1 files changed, 44 insertions, 113 deletions
diff --git a/linden/indra/llmessage/llhttpclient.cpp b/linden/indra/llmessage/llhttpclient.cpp index 3ede02a..22c0c68 100644 --- a/linden/indra/llmessage/llhttpclient.cpp +++ b/linden/indra/llmessage/llhttpclient.cpp | |||
@@ -1,4 +1,4 @@ | |||
1 | /** | 1 | /** |
2 | * @file llhttpclient.cpp | 2 | * @file llhttpclient.cpp |
3 | * @brief Implementation of classes for making HTTP requests. | 3 | * @brief Implementation of classes for making HTTP requests. |
4 | * | 4 | * |
@@ -46,75 +46,18 @@ | |||
46 | #include <curl/curl.h> | 46 | #include <curl/curl.h> |
47 | 47 | ||
48 | const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f; | 48 | const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f; |
49 | static std::string gCABundle; | 49 | //////////////////////////////////////////////////////////////////////////// |
50 | |||
51 | |||
52 | LLHTTPClient::Responder::Responder() | ||
53 | : mReferenceCount(0) | ||
54 | { | ||
55 | } | ||
56 | |||
57 | LLHTTPClient::Responder::~Responder() | ||
58 | { | ||
59 | } | ||
60 | |||
61 | // virtual | ||
62 | void LLHTTPClient::Responder::error(U32 status, const std::string& reason) | ||
63 | { | ||
64 | llinfos << "LLHTTPClient::Responder::error " | ||
65 | << status << ": " << reason << llendl; | ||
66 | } | ||
67 | |||
68 | // virtual | ||
69 | void LLHTTPClient::Responder::result(const LLSD& content) | ||
70 | { | ||
71 | } | ||
72 | |||
73 | // virtual | ||
74 | void LLHTTPClient::Responder::completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, | ||
75 | const LLIOPipe::buffer_ptr_t& buffer) | ||
76 | { | ||
77 | LLBufferStream istr(channels, buffer.get()); | ||
78 | LLSD content; | ||
79 | |||
80 | if (isGoodStatus(status)) | ||
81 | { | ||
82 | LLSDSerialize::fromXML(content, istr); | ||
83 | /* | ||
84 | const S32 parseError = -1; | ||
85 | if(LLSDSerialize::fromXML(content, istr) == parseError) | ||
86 | { | ||
87 | mStatus = 498; | ||
88 | mReason = "Client Parse Error"; | ||
89 | } | ||
90 | */ | ||
91 | } | ||
92 | |||
93 | completed(status, reason, content); | ||
94 | } | ||
95 | |||
96 | // virtual | ||
97 | void LLHTTPClient::Responder::completed(U32 status, const std::string& reason, const LLSD& content) | ||
98 | { | ||
99 | if(isGoodStatus(status)) | ||
100 | { | ||
101 | result(content); | ||
102 | } | ||
103 | else | ||
104 | { | ||
105 | error(status, reason); | ||
106 | } | ||
107 | } | ||
108 | 50 | ||
51 | // Responder class moved to LLCurl | ||
109 | 52 | ||
110 | namespace | 53 | namespace |
111 | { | 54 | { |
112 | class LLHTTPClientURLAdaptor : public LLURLRequestComplete | 55 | class LLHTTPClientURLAdaptor : public LLURLRequestComplete |
113 | { | 56 | { |
114 | public: | 57 | public: |
115 | LLHTTPClientURLAdaptor(LLHTTPClient::ResponderPtr responder) | 58 | LLHTTPClientURLAdaptor(LLCurl::ResponderPtr responder) |
116 | : mResponder(responder), | 59 | : mResponder(responder), mStatus(499), |
117 | mStatus(499), mReason("LLURLRequest complete w/no status") | 60 | mReason("LLURLRequest complete w/no status") |
118 | { | 61 | { |
119 | } | 62 | } |
120 | 63 | ||
@@ -129,18 +72,24 @@ namespace | |||
129 | } | 72 | } |
130 | 73 | ||
131 | virtual void complete(const LLChannelDescriptors& channels, | 74 | virtual void complete(const LLChannelDescriptors& channels, |
132 | const buffer_ptr_t& buffer) | 75 | const buffer_ptr_t& buffer) |
133 | { | 76 | { |
134 | if (mResponder.get()) | 77 | if (mResponder.get()) |
135 | { | 78 | { |
136 | mResponder->completedRaw(mStatus, mReason, channels, buffer); | 79 | mResponder->completedRaw(mStatus, mReason, channels, buffer); |
80 | mResponder->completedHeader(mStatus, mReason, mHeaderOutput); | ||
137 | } | 81 | } |
138 | } | 82 | } |
83 | virtual void header(const std::string& header, const std::string& value) | ||
84 | { | ||
85 | mHeaderOutput[header] = value; | ||
86 | } | ||
139 | 87 | ||
140 | private: | 88 | private: |
141 | LLHTTPClient::ResponderPtr mResponder; | 89 | LLCurl::ResponderPtr mResponder; |
142 | U32 mStatus; | 90 | U32 mStatus; |
143 | std::string mReason; | 91 | std::string mReason; |
92 | LLSD mHeaderOutput; | ||
144 | }; | 93 | }; |
145 | 94 | ||
146 | class Injector : public LLIOPipe | 95 | class Injector : public LLIOPipe |
@@ -250,13 +199,14 @@ namespace | |||
250 | LLPumpIO* theClientPump = NULL; | 199 | LLPumpIO* theClientPump = NULL; |
251 | } | 200 | } |
252 | 201 | ||
253 | static void request( | 202 | static void request(const std::string& url, |
254 | const std::string& url, | 203 | LLURLRequest::ERequestAction method, |
255 | LLURLRequest::ERequestAction method, | 204 | Injector* body_injector, |
256 | Injector* body_injector, | 205 | LLCurl::ResponderPtr responder, |
257 | LLHTTPClient::ResponderPtr responder, | 206 | const LLSD& headers = LLSD(), |
258 | const LLSD& headers, | 207 | const F32 timeout = HTTP_REQUEST_EXPIRY_SECS, |
259 | const F32 timeout=HTTP_REQUEST_EXPIRY_SECS) | 208 | S32 offset = 0, |
209 | S32 bytes = 0) | ||
260 | { | 210 | { |
261 | if (!LLHTTPClient::hasPump()) | 211 | if (!LLHTTPClient::hasPump()) |
262 | { | 212 | { |
@@ -266,7 +216,7 @@ static void request( | |||
266 | LLPumpIO::chain_t chain; | 216 | LLPumpIO::chain_t chain; |
267 | 217 | ||
268 | LLURLRequest *req = new LLURLRequest(method, url); | 218 | LLURLRequest *req = new LLURLRequest(method, url); |
269 | req->requestEncoding(""); | 219 | req->checkRootCertificate(true); |
270 | 220 | ||
271 | // Insert custom headers is the caller sent any | 221 | // Insert custom headers is the caller sent any |
272 | if (headers.isMap()) | 222 | if (headers.isMap()) |
@@ -291,10 +241,6 @@ static void request( | |||
291 | req->addHeader(header.str().c_str()); | 241 | req->addHeader(header.str().c_str()); |
292 | } | 242 | } |
293 | } | 243 | } |
294 | if (!gCABundle.empty()) | ||
295 | { | ||
296 | req->checkRootCertificate(true, gCABundle.c_str()); | ||
297 | } | ||
298 | req->setCallback(new LLHTTPClientURLAdaptor(responder)); | 244 | req->setCallback(new LLHTTPClientURLAdaptor(responder)); |
299 | 245 | ||
300 | if (method == LLURLRequest::HTTP_POST && gMessageSystem) | 246 | if (method == LLURLRequest::HTTP_POST && gMessageSystem) |
@@ -310,19 +256,26 @@ static void request( | |||
310 | 256 | ||
311 | chain.push_back(LLIOPipe::ptr_t(body_injector)); | 257 | chain.push_back(LLIOPipe::ptr_t(body_injector)); |
312 | } | 258 | } |
259 | |||
260 | if (method == LLURLRequest::HTTP_GET && (offset > 0 || bytes > 0)) | ||
261 | { | ||
262 | std::string range = llformat("Range: bytes=%d-%d", offset,offset+bytes-1); | ||
263 | req->addHeader(range.c_str()); | ||
264 | } | ||
265 | |||
313 | chain.push_back(LLIOPipe::ptr_t(req)); | 266 | chain.push_back(LLIOPipe::ptr_t(req)); |
314 | 267 | ||
315 | theClientPump->addChain(chain, timeout); | 268 | theClientPump->addChain(chain, timeout); |
316 | } | 269 | } |
317 | 270 | ||
318 | static void request( | 271 | |
319 | const std::string& url, | 272 | void LLHTTPClient::getByteRange(const std::string& url, |
320 | LLURLRequest::ERequestAction method, | 273 | S32 offset, S32 bytes, |
321 | Injector* body_injector, | 274 | ResponderPtr responder, |
322 | LLHTTPClient::ResponderPtr responder, | 275 | const LLSD& headers, |
323 | const F32 timeout=HTTP_REQUEST_EXPIRY_SECS) | 276 | const F32 timeout) |
324 | { | 277 | { |
325 | request(url, method, body_injector, responder, LLSD(), timeout); | 278 | request(url, LLURLRequest::HTTP_GET, NULL, responder, LLSD(), timeout, offset, bytes); |
326 | } | 279 | } |
327 | 280 | ||
328 | void LLHTTPClient::head(const std::string& url, ResponderPtr responder, const F32 timeout) | 281 | void LLHTTPClient::head(const std::string& url, ResponderPtr responder, const F32 timeout) |
@@ -334,10 +287,13 @@ void LLHTTPClient::get(const std::string& url, ResponderPtr responder, const LLS | |||
334 | { | 287 | { |
335 | request(url, LLURLRequest::HTTP_GET, NULL, responder, headers, timeout); | 288 | request(url, LLURLRequest::HTTP_GET, NULL, responder, headers, timeout); |
336 | } | 289 | } |
337 | 290 | void LLHTTPClient::getHeaderOnly(const std::string& url, ResponderPtr responder, const LLSD& headers, const F32 timeout) | |
338 | void LLHTTPClient::get(const std::string& url, ResponderPtr responder, const F32 timeout) | ||
339 | { | 291 | { |
340 | get(url, responder, LLSD(), timeout); | 292 | request(url, LLURLRequest::HTTP_HEAD, NULL, responder, headers, timeout); |
293 | } | ||
294 | void LLHTTPClient::getHeaderOnly(const std::string& url, ResponderPtr responder, const F32 timeout) | ||
295 | { | ||
296 | getHeaderOnly(url, responder, LLSD(), timeout); | ||
341 | } | 297 | } |
342 | 298 | ||
343 | void LLHTTPClient::get(const std::string& url, const LLSD& query, ResponderPtr responder, const LLSD& headers, const F32 timeout) | 299 | void LLHTTPClient::get(const std::string& url, const LLSD& query, ResponderPtr responder, const LLSD& headers, const F32 timeout) |
@@ -348,11 +304,6 @@ void LLHTTPClient::get(const std::string& url, const LLSD& query, ResponderPtr r | |||
348 | get(uri.asString(), responder, headers, timeout); | 304 | get(uri.asString(), responder, headers, timeout); |
349 | } | 305 | } |
350 | 306 | ||
351 | void LLHTTPClient::get(const std::string& url, const LLSD& query, ResponderPtr responder, const F32 timeout) | ||
352 | { | ||
353 | get(url, query, responder, LLSD(), timeout); | ||
354 | } | ||
355 | |||
356 | // A simple class for managing data returned from a curl http request. | 307 | // A simple class for managing data returned from a curl http request. |
357 | class LLHTTPBuffer | 308 | class LLHTTPBuffer |
358 | { | 309 | { |
@@ -388,6 +339,7 @@ private: | |||
388 | std::string mBuffer; | 339 | std::string mBuffer; |
389 | }; | 340 | }; |
390 | 341 | ||
342 | // *TODO: Deprecate (only used by dataserver) | ||
391 | // This call is blocking! This is probably usually bad. :( | 343 | // This call is blocking! This is probably usually bad. :( |
392 | LLSD LLHTTPClient::blockingGet(const std::string& url) | 344 | LLSD LLHTTPClient::blockingGet(const std::string& url) |
393 | { | 345 | { |
@@ -481,24 +433,3 @@ bool LLHTTPClient::hasPump() | |||
481 | { | 433 | { |
482 | return theClientPump != NULL; | 434 | return theClientPump != NULL; |
483 | } | 435 | } |
484 | |||
485 | void LLHTTPClient::setCABundle(const std::string& caBundle) | ||
486 | { | ||
487 | gCABundle = caBundle; | ||
488 | } | ||
489 | |||
490 | namespace boost | ||
491 | { | ||
492 | void intrusive_ptr_add_ref(LLHTTPClient::Responder* p) | ||
493 | { | ||
494 | ++p->mReferenceCount; | ||
495 | } | ||
496 | |||
497 | void intrusive_ptr_release(LLHTTPClient::Responder* p) | ||
498 | { | ||
499 | if(p && 0 == --p->mReferenceCount) | ||
500 | { | ||
501 | delete p; | ||
502 | } | ||
503 | } | ||
504 | }; | ||