summaryrefslogtreecommitdiff
path: root/indra/llcorehttp/_httpservice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcorehttp/_httpservice.cpp')
-rwxr-xr-x[-rw-r--r--]indra/llcorehttp/_httpservice.cpp196
1 files changed, 171 insertions, 25 deletions
diff --git a/indra/llcorehttp/_httpservice.cpp b/indra/llcorehttp/_httpservice.cpp
index 0825888d0f..c673e1be1d 100644..100755
--- a/indra/llcorehttp/_httpservice.cpp
+++ b/indra/llcorehttp/_httpservice.cpp
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2012, Linden Research, Inc.
+ * Copyright (C) 2012-2014, 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
@@ -40,9 +40,29 @@
#include "llthread.h"
+namespace
+{
+
+static const char * const LOG_CORE("CoreHttp");
+
+} // end anonymous namespace
+
+
namespace LLCore
{
+const HttpService::OptionDescriptor HttpService::sOptionDesc[] =
+{ // isLong isDynamic isGlobal isClass
+ { true, true, true, true }, // PO_CONNECTION_LIMIT
+ { true, true, false, true }, // PO_PER_HOST_CONNECTION_LIMIT
+ { false, false, true, false }, // PO_CA_PATH
+ { false, false, true, false }, // PO_CA_FILE
+ { false, true, true, false }, // PO_HTTP_PROXY
+ { true, true, true, false }, // PO_LLPROXY
+ { true, true, true, false }, // PO_TRACE
+ { true, true, false, true }, // PO_ENABLE_PIPELINING
+ { true, true, false, true } // PO_THROTTLE_RATE
+};
HttpService * HttpService::sInstance(NULL);
volatile HttpService::EState HttpService::sState(NOT_INITIALIZED);
@@ -51,15 +71,9 @@ HttpService::HttpService()
mExitRequested(0U),
mThread(NULL),
mPolicy(NULL),
- mTransport(NULL)
-{
- // Create the default policy class
- HttpPolicyClass pol_class;
- pol_class.set(HttpRequest::CP_CONNECTION_LIMIT, HTTP_CONNECTION_LIMIT_DEFAULT);
- pol_class.set(HttpRequest::CP_PER_HOST_CONNECTION_LIMIT, HTTP_CONNECTION_LIMIT_DEFAULT);
- pol_class.set(HttpRequest::CP_ENABLE_PIPELINING, 0L);
- mPolicyClasses.push_back(pol_class);
-}
+ mTransport(NULL),
+ mLastPolicy(0)
+{}
HttpService::~HttpService()
@@ -81,8 +95,8 @@ HttpService::~HttpService()
// Failed to join, expect problems ahead so do a hard termination.
mThread->cancel();
- LL_WARNS("CoreHttp") << "Destroying HttpService with running thread. Expect problems."
- << LL_ENDL;
+ LL_WARNS(LOG_CORE) << "Destroying HttpService with running thread. Expect problems."
+ << LL_ENDL;
}
}
}
@@ -149,13 +163,8 @@ void HttpService::term()
HttpRequest::policy_t HttpService::createPolicyClass()
{
- const HttpRequest::policy_t policy_class(mPolicyClasses.size());
- if (policy_class >= HTTP_POLICY_CLASS_LIMIT)
- {
- return 0;
- }
- mPolicyClasses.push_back(HttpPolicyClass());
- return policy_class;
+ mLastPolicy = mPolicy->createPolicyClass();
+ return mLastPolicy;
}
@@ -188,8 +197,8 @@ void HttpService::startThread()
}
// Push current policy definitions, enable policy & transport components
- mPolicy->start(mPolicyGlobal, mPolicyClasses);
- mTransport->start(mPolicyClasses.size());
+ mPolicy->start();
+ mTransport->start(mLastPolicy + 1);
mThread = new LLCoreInt::HttpThread(boost::bind(&HttpService::threadRun, this, _1));
sState = RUNNING;
@@ -322,14 +331,14 @@ HttpService::ELoopSpeed HttpService::processRequestQueue(ELoopSpeed loop)
{
// Setup for subsequent tracing
long tracing(HTTP_TRACE_OFF);
- mPolicy->getGlobalOptions().get(HttpRequest::GP_TRACE, &tracing);
+ mPolicy->getGlobalOptions().get(HttpRequest::PO_TRACE, &tracing);
op->mTracing = (std::max)(op->mTracing, int(tracing));
if (op->mTracing > HTTP_TRACE_OFF)
{
- LL_INFOS("CoreHttp") << "TRACE, FromRequestQueue, Handle: "
- << static_cast<HttpHandle>(op)
- << LL_ENDL;
+ LL_INFOS(LOG_CORE) << "TRACE, FromRequestQueue, Handle: "
+ << static_cast<HttpHandle>(op)
+ << LL_ENDL;
}
// Stage
@@ -345,4 +354,141 @@ HttpService::ELoopSpeed HttpService::processRequestQueue(ELoopSpeed loop)
}
+HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
+ long * ret_value)
+{
+ if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range
+ || opt >= HttpRequest::PO_LAST // ditto
+ || (! sOptionDesc[opt].mIsLong) // datatype is long
+ || (pclass != HttpRequest::GLOBAL_POLICY_ID && pclass > mLastPolicy) // pclass in valid range
+ || (pclass == HttpRequest::GLOBAL_POLICY_ID && ! sOptionDesc[opt].mIsGlobal) // global setting permitted
+ || (pclass != HttpRequest::GLOBAL_POLICY_ID && ! sOptionDesc[opt].mIsClass)) // class setting permitted
+ // can always get, no dynamic check
+ {
+ return HttpStatus(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
+ }
+
+ HttpStatus status;
+ if (pclass == HttpRequest::GLOBAL_POLICY_ID)
+ {
+ HttpPolicyGlobal & opts(mPolicy->getGlobalOptions());
+
+ status = opts.get(opt, ret_value);
+ }
+ else
+ {
+ HttpPolicyClass & opts(mPolicy->getClassOptions(pclass));
+
+ status = opts.get(opt, ret_value);
+ }
+
+ return status;
+}
+
+
+HttpStatus HttpService::getPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
+ std::string * ret_value)
+{
+ HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
+
+ if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range
+ || opt >= HttpRequest::PO_LAST // ditto
+ || (sOptionDesc[opt].mIsLong) // datatype is string
+ || (pclass != HttpRequest::GLOBAL_POLICY_ID && pclass > mLastPolicy) // pclass in valid range
+ || (pclass == HttpRequest::GLOBAL_POLICY_ID && ! sOptionDesc[opt].mIsGlobal) // global setting permitted
+ || (pclass != HttpRequest::GLOBAL_POLICY_ID && ! sOptionDesc[opt].mIsClass)) // class setting permitted
+ // can always get, no dynamic check
+ {
+ return status;
+ }
+
+ // Only global has string values
+ if (pclass == HttpRequest::GLOBAL_POLICY_ID)
+ {
+ HttpPolicyGlobal & opts(mPolicy->getGlobalOptions());
+
+ status = opts.get(opt, ret_value);
+ }
+
+ return status;
+}
+
+
+HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
+ long value, long * ret_value)
+{
+ HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
+
+ if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range
+ || opt >= HttpRequest::PO_LAST // ditto
+ || (! sOptionDesc[opt].mIsLong) // datatype is long
+ || (pclass != HttpRequest::GLOBAL_POLICY_ID && pclass > mLastPolicy) // pclass in valid range
+ || (pclass == HttpRequest::GLOBAL_POLICY_ID && ! sOptionDesc[opt].mIsGlobal) // global setting permitted
+ || (pclass != HttpRequest::GLOBAL_POLICY_ID && ! sOptionDesc[opt].mIsClass) // class setting permitted
+ || (RUNNING == sState && ! sOptionDesc[opt].mIsDynamic)) // dynamic setting permitted
+ {
+ return status;
+ }
+
+ if (pclass == HttpRequest::GLOBAL_POLICY_ID)
+ {
+ HttpPolicyGlobal & opts(mPolicy->getGlobalOptions());
+
+ status = opts.set(opt, value);
+ if (status && ret_value)
+ {
+ status = opts.get(opt, ret_value);
+ }
+ }
+ else
+ {
+ HttpPolicyClass & opts(mPolicy->getClassOptions(pclass));
+
+ status = opts.set(opt, value);
+ if (status)
+ {
+ mTransport->policyUpdated(pclass);
+ if (ret_value)
+ {
+ status = opts.get(opt, ret_value);
+ }
+ }
+ }
+
+ return status;
+}
+
+
+HttpStatus HttpService::setPolicyOption(HttpRequest::EPolicyOption opt, HttpRequest::policy_t pclass,
+ const std::string & value, std::string * ret_value)
+{
+ HttpStatus status(HttpStatus::LLCORE, LLCore::HE_INVALID_ARG);
+
+ if (opt < HttpRequest::PO_CONNECTION_LIMIT // option must be in range
+ || opt >= HttpRequest::PO_LAST // ditto
+ || (sOptionDesc[opt].mIsLong) // datatype is string
+ || (pclass != HttpRequest::GLOBAL_POLICY_ID && pclass > mLastPolicy) // pclass in valid range
+ || (pclass == HttpRequest::GLOBAL_POLICY_ID && ! sOptionDesc[opt].mIsGlobal) // global setting permitted
+ || (pclass != HttpRequest::GLOBAL_POLICY_ID && ! sOptionDesc[opt].mIsClass) // class setting permitted
+ || (RUNNING == sState && ! sOptionDesc[opt].mIsDynamic)) // dynamic setting permitted
+ {
+ return status;
+ }
+
+ // String values are always global (at this time).
+ if (pclass == HttpRequest::GLOBAL_POLICY_ID)
+ {
+ HttpPolicyGlobal & opts(mPolicy->getGlobalOptions());
+
+ status = opts.set(opt, value);
+ if (status && ret_value)
+ {
+ status = opts.get(opt, ret_value);
+ }
+ }
+
+ return status;
+}
+
+
} // end namespace LLCore