summaryrefslogtreecommitdiff
path: root/indra/llcorehttp
diff options
context:
space:
mode:
authorOz Linden <oz@lindenlab.com>2017-08-15 15:28:52 +0000
committerOz Linden <oz@lindenlab.com>2017-08-15 15:28:52 +0000
commitbafe85a0f6e86912c43caaf4779cb4daa54c9ba3 (patch)
tree4c077382fb2eeb92cd7c6efdad3a9ea08f82b193 /indra/llcorehttp
parent4cc6d44ef88196c940e9f7e74243146549a11018 (diff)
parent79856e655432a30f5bba2e8d7adecdc3626ce94f (diff)
Merged in rider_linden/viewer64-gundam (pull request #18)
Default
Diffstat (limited to 'indra/llcorehttp')
-rw-r--r--indra/llcorehttp/CMakeLists.txt2
-rw-r--r--indra/llcorehttp/_httpoprequest.cpp27
-rw-r--r--indra/llcorehttp/_httpoprequest.h4
-rw-r--r--indra/llcorehttp/_httppolicy.cpp3
-rw-r--r--indra/llcorehttp/_httpservice.cpp49
-rw-r--r--indra/llcorehttp/bufferarray.cpp22
-rw-r--r--indra/llcorehttp/httprequest.cpp4
-rw-r--r--indra/llcorehttp/httprequest.h2
-rw-r--r--indra/llcorehttp/httpresponse.h10
-rw-r--r--indra/llcorehttp/httpstats.cpp108
-rw-r--r--indra/llcorehttp/httpstats.h74
11 files changed, 284 insertions, 21 deletions
diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt
index 7482fc577f..435fb09aa4 100644
--- a/indra/llcorehttp/CMakeLists.txt
+++ b/indra/llcorehttp/CMakeLists.txt
@@ -30,6 +30,7 @@ set(llcorehttp_SOURCE_FILES
httpoptions.cpp
httprequest.cpp
httpresponse.cpp
+ httpstats.cpp
_httplibcurl.cpp
_httpopcancel.cpp
_httpoperation.cpp
@@ -57,6 +58,7 @@ set(llcorehttp_HEADER_FILES
httpoptions.h
httprequest.h
httpresponse.h
+ httpstats.h
_httpinternal.h
_httplibcurl.h
_httpopcancel.h
diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp
index 07cc0e4625..f526af37b5 100644
--- a/indra/llcorehttp/_httpoprequest.cpp
+++ b/indra/llcorehttp/_httpoprequest.cpp
@@ -47,6 +47,8 @@
#include "llhttpconstants.h"
#include "llproxy.h"
+#include "httpstats.h"
+
// *DEBUG: "[curl:bugs] #1420" problem and testing.
//
// A pipelining problem, https://sourceforge.net/p/curl/bugs/1420/,
@@ -245,6 +247,8 @@ void HttpOpRequest::visitNotifier(HttpRequest * request)
response->setHeaders(mReplyHeaders);
response->setRequestURL(mReqURL);
+ response->setRequestMethod(methodToString(mReqMethod));
+
if (mReplyOffset || mReplyLength)
{
// Got an explicit offset/length in response
@@ -805,6 +809,7 @@ size_t HttpOpRequest::writeCallback(void * data, size_t size, size_t nmemb, void
}
const size_t req_size(size * nmemb);
const size_t write_size(op->mReplyBody->append(static_cast<char *>(data), req_size));
+ HTTPStats::instance().recordDataDown(write_size);
return write_size;
}
@@ -833,7 +838,8 @@ size_t HttpOpRequest::readCallback(void * data, size_t size, size_t nmemb, void
const size_t do_size((std::min)(req_size, body_size - op->mCurlBodyPos));
const size_t read_size(op->mReqBody->read(op->mCurlBodyPos, static_cast<char *>(data), do_size));
- op->mCurlBodyPos += read_size;
+ HTTPStats::instance().recordDataUp(read_size);
+ op->mCurlBodyPos += read_size;
return read_size;
}
@@ -1138,6 +1144,25 @@ int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffe
return 0;
}
+std::string HttpOpRequest::methodToString(const HttpOpRequest::EMethod &e)
+{
+ if (e == HOR_COPY)
+ return "COPY";
+ else if (e == HOR_DELETE)
+ return "DELETE";
+ else if (e == HOR_GET)
+ return "GET";
+ else if (e == HOR_MOVE)
+ return "MOVE";
+ else if (e == HOR_PATCH)
+ return "PATCH";
+ else if (e == HOR_POST)
+ return "POST";
+ else if (e == HOR_PUT)
+ return "PUT";
+
+ return "UNKNOWN";
+}
} // end namespace LLCore
diff --git a/indra/llcorehttp/_httpoprequest.h b/indra/llcorehttp/_httpoprequest.h
index dbcc57d0fd..201c37d5c3 100644
--- a/indra/llcorehttp/_httpoprequest.h
+++ b/indra/llcorehttp/_httpoprequest.h
@@ -87,7 +87,8 @@ public:
HOR_COPY,
HOR_MOVE
};
-
+ static std::string methodToString(const EMethod &);
+
virtual void stageFromRequest(HttpService *);
virtual void stageFromReady(HttpService *);
virtual void stageFromActive(HttpService *);
@@ -235,6 +236,7 @@ public:
}; // end class HttpOpRequest
+
/// HttpOpRequestCompare isn't an operation but a uniform comparison
/// functor for STL containers that order by priority. Mainly
/// used for the ready queue container but defined here.
diff --git a/indra/llcorehttp/_httppolicy.cpp b/indra/llcorehttp/_httppolicy.cpp
index b2709b53ec..a302db8b46 100644
--- a/indra/llcorehttp/_httppolicy.cpp
+++ b/indra/llcorehttp/_httppolicy.cpp
@@ -34,6 +34,7 @@
#include "_httppolicyclass.h"
#include "lltimer.h"
+#include "httpstats.h"
namespace
{
@@ -448,6 +449,8 @@ bool HttpPolicy::stageAfterCompletion(const HttpOpRequest::ptr_t &op)
}
op->stageFromActive(mService);
+
+ HTTPStats::instance().recordResultCode(op->mStatus.getType());
return false; // not active
}
diff --git a/indra/llcorehttp/_httpservice.cpp b/indra/llcorehttp/_httpservice.cpp
index 6c39fdc61b..49d865cbfa 100644
--- a/indra/llcorehttp/_httpservice.cpp
+++ b/indra/llcorehttp/_httpservice.cpp
@@ -38,7 +38,8 @@
#include "lltimer.h"
#include "llthread.h"
-
+#include "llexception.h"
+#include "llmemory.h"
namespace
{
@@ -293,22 +294,42 @@ void HttpService::threadRun(LLCoreInt::HttpThread * thread)
ELoopSpeed loop(REQUEST_SLEEP);
while (! mExitRequested)
{
- loop = processRequestQueue(loop);
+ try
+ {
+ loop = processRequestQueue(loop);
- // Process ready queue issuing new requests as needed
- ELoopSpeed new_loop = mPolicy->processReadyQueue();
- loop = (std::min)(loop, new_loop);
+ // Process ready queue issuing new requests as needed
+ ELoopSpeed new_loop = mPolicy->processReadyQueue();
+ loop = (std::min)(loop, new_loop);
- // Give libcurl some cycles
- new_loop = mTransport->processTransport();
- loop = (std::min)(loop, new_loop);
+ // Give libcurl some cycles
+ new_loop = mTransport->processTransport();
+ loop = (std::min)(loop, new_loop);
- // Determine whether to spin, sleep briefly or sleep for next request
- if (REQUEST_SLEEP != loop)
- {
- ms_sleep(HTTP_SERVICE_LOOP_SLEEP_NORMAL_MS);
- }
- }
+ // Determine whether to spin, sleep briefly or sleep for next request
+ if (REQUEST_SLEEP != loop)
+ {
+ ms_sleep(HTTP_SERVICE_LOOP_SLEEP_NORMAL_MS);
+ }
+ }
+ catch (const LLContinueError&)
+ {
+ LOG_UNHANDLED_EXCEPTION("");
+ }
+ catch (std::bad_alloc)
+ {
+ LLMemory::logMemoryInfo(TRUE);
+
+ //output possible call stacks to log file.
+ LLError::LLCallStacks::print();
+
+ LL_ERRS() << "Bad memory allocation in HttpService::threadRun()!" << LL_ENDL;
+ }
+ catch (...)
+ {
+ CRASH_ON_UNHANDLED_EXCEPTION("");
+ }
+ }
shutdown();
sState = STOPPED;
diff --git a/indra/llcorehttp/bufferarray.cpp b/indra/llcorehttp/bufferarray.cpp
index 8eaaeed710..be534b3ce4 100644
--- a/indra/llcorehttp/bufferarray.cpp
+++ b/indra/llcorehttp/bufferarray.cpp
@@ -25,6 +25,8 @@
*/
#include "bufferarray.h"
+#include "llexception.h"
+#include "llmemory.h"
// BufferArray is a list of chunks, each a BufferArray::Block, of contiguous
@@ -140,8 +142,22 @@ size_t BufferArray::append(const void * src, size_t len)
{
mBlocks.reserve(mBlocks.size() + 5);
}
- Block * block = Block::alloc(BLOCK_ALLOC_SIZE);
- memcpy(block->mData, c_src, copy_len);
+ Block * block;
+ try
+ {
+ block = Block::alloc(BLOCK_ALLOC_SIZE);
+ }
+ catch (std::bad_alloc)
+ {
+ LLMemory::logMemoryInfo(TRUE);
+
+ //output possible call stacks to log file.
+ LLError::LLCallStacks::print();
+
+ LL_WARNS() << "Bad memory allocation in thrown by Block::alloc in read!" << LL_ENDL;
+ break;
+ }
+ memcpy(block->mData, c_src, copy_len);
block->mUsed = copy_len;
llassert_always(block->mUsed <= block->mAlloced);
mBlocks.push_back(block);
@@ -149,7 +165,7 @@ size_t BufferArray::append(const void * src, size_t len)
c_src += copy_len;
len -= copy_len;
}
- return ret;
+ return ret - len;
}
diff --git a/indra/llcorehttp/httprequest.cpp b/indra/llcorehttp/httprequest.cpp
index e09f0c3b18..2687f77217 100644
--- a/indra/llcorehttp/httprequest.cpp
+++ b/indra/llcorehttp/httprequest.cpp
@@ -37,7 +37,7 @@
#include "_httpopsetget.h"
#include "lltimer.h"
-
+#include "httpstats.h"
namespace
{
@@ -62,6 +62,8 @@ HttpRequest::HttpRequest()
mRequestQueue->addRef();
mReplyQueue.reset( new HttpReplyQueue() );
+
+ HTTPStats::instance().recordHTTPRequest();
}
diff --git a/indra/llcorehttp/httprequest.h b/indra/llcorehttp/httprequest.h
index 17cfdcd7b6..a418eb6a7a 100644
--- a/indra/llcorehttp/httprequest.h
+++ b/indra/llcorehttp/httprequest.h
@@ -680,7 +680,7 @@ private:
/// @}
// End Global State
// ====================================
-
+
}; // end class HttpRequest
diff --git a/indra/llcorehttp/httpresponse.h b/indra/llcorehttp/httpresponse.h
index 0bfa4585c7..b834085e5c 100644
--- a/indra/llcorehttp/httpresponse.h
+++ b/indra/llcorehttp/httpresponse.h
@@ -204,6 +204,15 @@ public:
return mRequestUrl;
}
+ void setRequestMethod(const std::string &method)
+ {
+ mRequestMethod = method;
+ }
+
+ const std::string &getRequestMethod() const
+ {
+ return mRequestMethod;
+ }
protected:
// Response data here
@@ -217,6 +226,7 @@ protected:
unsigned int mRetries;
unsigned int m503Retries;
std::string mRequestUrl;
+ std::string mRequestMethod;
TransferStats::ptr_t mStats;
};
diff --git a/indra/llcorehttp/httpstats.cpp b/indra/llcorehttp/httpstats.cpp
new file mode 100644
index 0000000000..b2de7f51ff
--- /dev/null
+++ b/indra/llcorehttp/httpstats.cpp
@@ -0,0 +1,108 @@
+/**
+ * @file llviewerstats.cpp
+ * @brief LLViewerStats class implementation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "httpstats.h"
+#include "llerror.h"
+
+namespace LLCore
+{
+HTTPStats::HTTPStats()
+{
+ resetStats();
+}
+
+
+HTTPStats::~HTTPStats()
+{
+}
+
+void HTTPStats::resetStats()
+{
+ mResutCodes.clear();
+ mDataDown.reset();
+ mDataUp.reset();
+ mRequests = 0;
+}
+
+
+void HTTPStats::recordResultCode(S32 code)
+{
+ std::map<S32, S32>::iterator it;
+
+ it = mResutCodes.find(code);
+
+ if (it == mResutCodes.end())
+ mResutCodes[code] = 1;
+ else
+ (*it).second = (*it).second + 1;
+
+}
+
+namespace
+{
+ std::string byte_count_converter(F32 bytes)
+ {
+ static const char unit_suffix[] = { 'B', 'K', 'M', 'G' };
+
+ F32 value = bytes;
+ int suffix = 0;
+
+ while ((value > 1024.0) && (suffix < 3))
+ {
+ value /= 1024.0;
+ ++suffix;
+ }
+
+ std::stringstream out;
+
+ out << std::setprecision(4) << value << unit_suffix[suffix];
+
+ return out.str();
+ }
+}
+
+void HTTPStats::dumpStats()
+{
+ std::stringstream out;
+
+ out << "HTTP DATA SUMMARY" << std::endl;
+ out << "HTTP Transfer counts:" << std::endl;
+ out << "Data Sent: " << byte_count_converter(mDataUp.getSum()) << " (" << mDataUp.getSum() << ")" << std::endl;
+ out << "Data Recv: " << byte_count_converter(mDataDown.getSum()) << " (" << mDataDown.getSum() << ")" << std::endl;
+ out << "Total requests: " << mRequests << "(request objects created)" << std::endl;
+ out << std::endl;
+ out << "Result Codes:" << std::endl << "--- -----" << std::endl;
+
+ for (std::map<S32, S32>::iterator it = mResutCodes.begin(); it != mResutCodes.end(); ++it)
+ {
+ out << (*it).first << " " << (*it).second << std::endl;
+ }
+
+ LL_WARNS("HTTP Core") << out.str() << LL_ENDL;
+}
+
+
+}
diff --git a/indra/llcorehttp/httpstats.h b/indra/llcorehttp/httpstats.h
new file mode 100644
index 0000000000..2c713cb548
--- /dev/null
+++ b/indra/llcorehttp/httpstats.h
@@ -0,0 +1,74 @@
+/**
+ * @file llviewerim_peningtats.h
+ * @brief LLViewerStats class header file
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLVIEWERSTATS_H
+#define LL_LLVIEWERSTATS_H
+
+#include "lltracerecording.h"
+#include "lltrace.h"
+#include "llstatsaccumulator.h"
+#include "llsingleton.h"
+#include "llsd.h"
+
+namespace LLCore
+{
+ class HTTPStats : public LLSingleton<HTTPStats>
+ {
+ LLSINGLETON(HTTPStats);
+ virtual ~HTTPStats();
+
+ public:
+ void resetStats();
+
+ typedef LLStatsAccumulator StatsAccumulator;
+
+ void recordDataDown(size_t bytes)
+ {
+ mDataDown.push(bytes);
+ }
+
+ void recordDataUp(size_t bytes)
+ {
+ mDataUp.push(bytes);
+ }
+
+ void recordHTTPRequest() { ++mRequests; }
+
+ void recordResultCode(S32 code);
+
+ void dumpStats();
+ private:
+ StatsAccumulator mDataDown;
+ StatsAccumulator mDataUp;
+
+ S32 mRequests;
+
+ std::map<S32, S32> mResutCodes;
+ };
+
+
+}
+#endif // LL_LLVIEWERSTATS_H