diff --git a/indra/llmessage/llcurlrequest.cpp b/indra/llmessage/llcurlrequest.cpp index fffddcd46..702904a42 100644 --- a/indra/llmessage/llcurlrequest.cpp +++ b/indra/llmessage/llcurlrequest.cpp @@ -129,6 +129,8 @@ bool Request::post3(std::string const& url, AIHTTPHeaders const& headers, LLSD c LLBufferStream buffer_stream(buffer_w->sChannels, buffer_w->getInput().get()); LLSDSerialize::toXML(data, buffer_stream); + // Need to flush the LLBufferStream or countAfter() returns more than the written data. + buffer_stream << std::flush; S32 bytes = buffer_w->getInput()->countAfter(buffer_w->sChannels.out(), NULL); buffered_easy_request_w->setPost(bytes); buffered_easy_request_w->addHeader("Content-Type: application/llsd+xml"); diff --git a/indra/llmessage/llfiltersd2xmlrpc.cpp b/indra/llmessage/llfiltersd2xmlrpc.cpp index e0ca056a5..9828a3e30 100644 --- a/indra/llmessage/llfiltersd2xmlrpc.cpp +++ b/indra/llmessage/llfiltersd2xmlrpc.cpp @@ -332,7 +332,7 @@ LLIOPipe::EStatus LLFilterSD2XMLRPCResponse::process_impl( // we have everyting in the buffer, so turn the structure data rpc // response into an xml rpc response. LLBufferStream stream(channels, buffer.get()); - stream << XML_HEADER << XMLRPC_METHOD_RESPONSE_HEADER; + stream << XML_HEADER << XMLRPC_METHOD_RESPONSE_HEADER << std::flush; // Flush, or buffer->count() returns too much! LLSD sd; LLSDSerialize::fromNotation(sd, stream, buffer->count(channels.in())); @@ -484,7 +484,7 @@ LLIOPipe::EStatus LLFilterSD2XMLRPCRequest::process_impl( break; } - stream << XMLRPC_REQUEST_FOOTER; + stream << XMLRPC_REQUEST_FOOTER << std::flush; return STATUS_DONE; } @@ -647,7 +647,7 @@ LLIOPipe::EStatus LLFilterXMLRPCResponse2LLSD::process_impl( fault_string.assign(fault_str); } stream << "'" << LLSDNotationFormatter::escapeString(fault_string) - << "'" < 0 && ostream.count_in() == 0); + // Need to flush the LLBufferStream or count_out() returns more than the written data. + ostream << std::flush; return ostream.count_out(); } @@ -68,6 +68,7 @@ class RawInjector : public Injector { LLBufferStream ostream(channels, buffer.get()); ostream.write(mData, mSize); + ostream << std::flush; // Always flush a LLBufferStream when done writing to it. return mSize; } @@ -84,21 +85,32 @@ class FileInjector : public Injector /*virtual*/ U32 get_body(LLChannelDescriptors const& channels, buffer_ptr_t& buffer) { - LLBufferStream ostream(channels, buffer.get()); - llifstream fstream(mFilename, std::iostream::binary | std::iostream::out); if (!fstream.is_open()) throw AICurlNoBody(llformat("Failed to open \"%s\".", mFilename.c_str())); - + LLBufferStream ostream(channels, buffer.get()); + char tmpbuf[4096]; +#ifdef SHOW_ASSERT + size_t total_len = 0; fstream.seekg(0, std::ios::end); - U32 fileSize = fstream.tellg(); + size_t file_size = fstream.tellg(); fstream.seekg(0, std::ios::beg); - std::vector fileBuffer(fileSize); - fstream.read(&fileBuffer[0], fileSize); - ostream.write(&fileBuffer[0], fileSize); +#endif + while (fstream) + { + std::streamsize len = fstream.readsome(tmpbuf, sizeof(tmpbuf)); + if (len > 0) + { + ostream.write(tmpbuf, len); +#ifdef SHOW_ASSERT + total_len += len; +#endif + } + } fstream.close(); - - return fileSize; + ostream << std::flush; + llassert(total_len == file_size && total_len == ostream.count_out()); + return ostream.count_out(); } std::string const mFilename; @@ -120,6 +132,7 @@ public: std::vector fileBuffer(fileSize); vfile.read(&fileBuffer[0], fileSize); ostream.write((char*)&fileBuffer[0], fileSize); + ostream << std::flush; return fileSize; } diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp index 9c1a6677e..6e2ec7f9b 100644 --- a/indra/llmessage/lliohttpserver.cpp +++ b/indra/llmessage/lliohttpserver.cpp @@ -272,6 +272,7 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl( context[CONTEXT_RESPONSE][CONTEXT_HEADERS] = headers; LLBufferStream ostr(channels, buffer.get()); LLSDSerialize::toXML(mGoodResult, ostr); + ostr << std::flush; return STATUS_DONE; } @@ -284,7 +285,7 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl( context[CONTEXT_RESPONSE]["statusCode"] = mStatusCode; context[CONTEXT_RESPONSE]["statusMessage"] = mStatusMessage; LLBufferStream ostr(channels, buffer.get()); - ostr << mStatusMessage; + ostr << mStatusMessage << std::flush; return STATUS_DONE; } @@ -293,7 +294,7 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl( context[CONTEXT_RESPONSE][CONTEXT_HEADERS] = mHeaders; context[CONTEXT_RESPONSE]["statusCode"] = mStatusCode; LLBufferStream ostr(channels, buffer.get()); - ostr << mStatusMessage; + ostr << mStatusMessage << std::flush; return STATUS_DONE; } @@ -633,7 +634,7 @@ void LLHTTPResponder::markBad( LLBufferStream out(channels, buffer.get()); out << HTTP_VERSION_STR << " 400 Bad Request\r\n\r\n\n" << "Bad Request\n\nBad Request.\n" - << "\n\n"; + << "\n\n" << std::flush; } static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_RESPONDER("HTTP Responder"); @@ -926,7 +927,7 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl( mState = STATE_SHORT_CIRCUIT; str << HTTP_VERSION_STR << " 404 Not Found\r\n\r\n\n" << "Not Found\n\nNode '" << mAbsPathAndQuery - << "' not found.\n\n\n"; + << "' not found.\n\n\n" << std::flush; } } diff --git a/indra/newview/hipporestrequest.cpp b/indra/newview/hipporestrequest.cpp index e3c5e0f82..e36c081d7 100644 --- a/indra/newview/hipporestrequest.cpp +++ b/indra/newview/hipporestrequest.cpp @@ -146,6 +146,7 @@ class BodyDataRaw : public Injector { LLBufferStream ostream(channels, buffer.get()); ostream.write(mData.data(), mData.size()); + ostream << std::flush; return mData.size(); } @@ -174,6 +175,7 @@ class BodyDataXml : public Injector mTree->write(data); LLBufferStream ostream(channels, buffer.get()); ostream.write(data.data(), data.size()); + ostream << std::flush; return data.size(); }