aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmessage/llhttpclient.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llmessage/llhttpclient.cpp')
-rw-r--r--linden/indra/llmessage/llhttpclient.cpp157
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
48const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f; 48const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f;
49static std::string gCABundle; 49////////////////////////////////////////////////////////////////////////////
50
51
52LLHTTPClient::Responder::Responder()
53 : mReferenceCount(0)
54{
55}
56
57LLHTTPClient::Responder::~Responder()
58{
59}
60
61// virtual
62void LLHTTPClient::Responder::error(U32 status, const std::string& reason)
63{
64 llinfos << "LLHTTPClient::Responder::error "
65 << status << ": " << reason << llendl;
66}
67
68// virtual
69void LLHTTPClient::Responder::result(const LLSD& content)
70{
71}
72
73// virtual
74void 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
97void 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
110namespace 53namespace
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
253static void request( 202static 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
318static void request( 271
319 const std::string& url, 272void 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
328void LLHTTPClient::head(const std::string& url, ResponderPtr responder, const F32 timeout) 281void 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 290void LLHTTPClient::getHeaderOnly(const std::string& url, ResponderPtr responder, const LLSD& headers, const F32 timeout)
338void 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}
294void LLHTTPClient::getHeaderOnly(const std::string& url, ResponderPtr responder, const F32 timeout)
295{
296 getHeaderOnly(url, responder, LLSD(), timeout);
341} 297}
342 298
343void LLHTTPClient::get(const std::string& url, const LLSD& query, ResponderPtr responder, const LLSD& headers, const F32 timeout) 299void 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
351void 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.
357class LLHTTPBuffer 308class 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. :(
392LLSD LLHTTPClient::blockingGet(const std::string& url) 344LLSD 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
485void LLHTTPClient::setCABundle(const std::string& caBundle)
486{
487 gCABundle = caBundle;
488}
489
490namespace 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};