diff --git a/indra/llmessage/aicurl.cpp b/indra/llmessage/aicurl.cpp index c68399059..6d3cbf4b0 100644 --- a/indra/llmessage/aicurl.cpp +++ b/indra/llmessage/aicurl.cpp @@ -1191,9 +1191,7 @@ void CurlResponderBuffer::resetState(AICurlEasyRequest_wat& curl_easy_request_w) curl_easy_request_w->resetState(); mOutput.reset(); - - mInput.str(""); - mInput.clear(); + mInput.reset(); mHeaderOutput.str(""); mHeaderOutput.clear(); @@ -1211,6 +1209,10 @@ void CurlResponderBuffer::prepRequest(AICurlEasyRequest_wat& curl_easy_request_w curl_easy_request_w->setoptString(CURLOPT_ENCODING, ""); } + mInput.reset(new LLBufferArray); + mInput->setThreaded(true); + mLastRead = NULL; + mOutput.reset(new LLBufferArray); mOutput->setThreaded(true); @@ -1271,16 +1273,10 @@ size_t CurlResponderBuffer::curlReadCallback(char* data, size_t size, size_t nme // to make sure that callbacks and destruction aren't done simultaneously. AICurlEasyRequest_wat buffered_easy_request_w(*lockobj); + S32 bytes = size * nmemb; // The maximum amount to read. AICurlResponderBuffer_wat buffer_w(*lockobj); - S32 n = size * nmemb; - S32 startpos = buffer_w->getInput().tellg(); - buffer_w->getInput().seekg(0, std::ios::end); - S32 endpos = buffer_w->getInput().tellg(); - buffer_w->getInput().seekg(startpos, std::ios::beg); - S32 maxn = endpos - startpos; - n = llmin(n, maxn); - buffer_w->getInput().read(data, n); - return n; + buffer_w->mLastRead = buffer_w->getInput()->readAfter(sChannels.out(), buffer_w->mLastRead, (U8*)data, bytes); + return bytes; // Return the amount actually read. } //static diff --git a/indra/llmessage/aicurlprivate.h b/indra/llmessage/aicurlprivate.h index 38ce00b5c..14a8b0fa2 100644 --- a/indra/llmessage/aicurlprivate.h +++ b/indra/llmessage/aicurlprivate.h @@ -291,9 +291,9 @@ class CurlResponderBuffer : protected AICurlEasyHandleEvents { void resetState(AICurlEasyRequest_wat& curl_easy_request_w); void prepRequest(AICurlEasyRequest_wat& buffered_curl_easy_request_w, std::vector const& headers, AICurlInterface::ResponderPtr responder, S32 time_out = 0, bool post = false); - std::stringstream& getInput() { return mInput; } - std::stringstream& getHeaderOutput() { return mHeaderOutput; } - LLIOPipe::buffer_ptr_t& getOutput() { return mOutput; } + LLIOPipe::buffer_ptr_t& getInput(void) { return mInput; } + std::stringstream& getHeaderOutput(void) { return mHeaderOutput; } + LLIOPipe::buffer_ptr_t& getOutput(void) { return mOutput; } // Called if libcurl doesn't deliver within CurlRequestTimeOut seconds. void timed_out(void); @@ -307,13 +307,14 @@ class CurlResponderBuffer : protected AICurlEasyHandleEvents { /*virtual*/ void removed_from_multi_handle(AICurlEasyRequest_wat& curl_easy_request_w); private: - std::stringstream mInput; + LLIOPipe::buffer_ptr_t mInput; + U8* mLastRead; // Pointer into mInput where we last stopped reading (or NULL to start at the beginning). std::stringstream mHeaderOutput; LLIOPipe::buffer_ptr_t mOutput; AICurlInterface::ResponderPtr mResponder; public: - static LLChannelDescriptors const sChannels; // Channel object for mOutput: we ONLY use channel 0, so this can be a constant. + static LLChannelDescriptors const sChannels; // Channel object for mInput (channel out()) and mOutput (channel in()). private: // This class may only be created by constructing a ThreadSafeBufferedCurlEasyRequest. diff --git a/indra/newview/llcurlrequest.cpp b/indra/newview/llcurlrequest.cpp index e50bd040e..0c566fed2 100644 --- a/indra/newview/llcurlrequest.cpp +++ b/indra/newview/llcurlrequest.cpp @@ -41,6 +41,8 @@ #include "llsdserialize.h" #include "llcurlrequest.h" +#include "llbuffer.h" +#include "llbufferstream.h" #include "statemachine/aicurleasyrequeststatemachine.h" //----------------------------------------------------------------------------- @@ -94,8 +96,11 @@ bool Request::post(std::string const& url, headers_t const& headers, std::string buffer_w->prepRequest(buffered_easy_request_w, headers, responder); - buffer_w->getInput().write(data.data(), data.size()); - S32 bytes = buffer_w->getInput().str().length(); + U32 bytes = data.size(); + bool success = buffer_w->getInput()->append(buffer_w->sChannels.out(), (U8 const*)data.data(), bytes); + llassert_always(success); // AIFIXME: Maybe throw an error. + if (!success) + return false; buffered_easy_request_w->setPost(NULL, bytes); buffered_easy_request_w->addHeader("Content-Type: application/octet-stream"); buffered_easy_request_w->finalizeRequest(url); @@ -121,8 +126,9 @@ bool Request::post(std::string const& url, headers_t const& headers, LLSD const& buffer_w->prepRequest(buffered_easy_request_w, headers, responder); - LLSDSerialize::toXML(data, buffer_w->getInput()); - S32 bytes = buffer_w->getInput().str().length(); + LLBufferStream buffer_stream(buffer_w->sChannels, buffer_w->getInput().get()); + LLSDSerialize::toXML(data, buffer_stream); + S32 bytes = buffer_w->getInput()->countAfter(buffer_w->sChannels.out(), NULL); buffered_easy_request_w->setPost(NULL, bytes); buffered_easy_request_w->addHeader("Content-Type: application/llsd+xml"); buffered_easy_request_w->finalizeRequest(url);