diff --git a/indra/llmessage/aicurl.cpp b/indra/llmessage/aicurl.cpp index c68399059..2f90b8e6e 100644 --- a/indra/llmessage/aicurl.cpp +++ b/indra/llmessage/aicurl.cpp @@ -200,15 +200,15 @@ static bool need_renegotiation_hack = false; void ssl_init(void) { // The version identifier format is: MMNNFFPPS: major minor fix patch status. - int const compiled_openSLL_major = (OPENSSL_VERSION_NUMBER >> 28) & 0xff; - int const compiled_openSLL_minor = (OPENSSL_VERSION_NUMBER >> 20) & 0xff; + int const compiled_openSSL_major = (OPENSSL_VERSION_NUMBER >> 28) & 0xff; + int const compiled_openSSL_minor = (OPENSSL_VERSION_NUMBER >> 20) & 0xff; unsigned long const ssleay = SSLeay(); - int const linked_openSLL_major = (ssleay >> 28) & 0xff; - int const linked_openSLL_minor = (ssleay >> 20) & 0xff; + int const linked_openSSL_major = (ssleay >> 28) & 0xff; + int const linked_openSSL_minor = (ssleay >> 20) & 0xff; // Check if dynamically loaded version is compatible with the one we compiled against. // As off version 1.0.0 also minor versions are compatible. - if (linked_openSLL_major != compiled_openSLL_major || - (compiled_openSLL_major == 0 && linked_openSLL_minor != compiled_openSLL_minor)) + if (linked_openSSL_major != compiled_openSSL_major || + (linked_openSSL_major == 0 && linked_openSSL_minor != compiled_openSSL_minor)) { llerrs << "The viewer was compiled against " << OPENSSL_VERSION_TEXT << " but linked against " << SSLeay_version(SSLEAY_VERSION) << @@ -949,7 +949,7 @@ static int curl_debug_cb(CURL*, curl_infotype infotype, char* buf, size_t size, { LibcwDoutStream << size << " bytes"; bool finished = false; - int i = 0; + size_t i = 0; while (i < size) { char c = buf[i]; @@ -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);