summaryrefslogtreecommitdiff
path: root/indra/llcorehttp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcorehttp')
-rw-r--r--indra/llcorehttp/CMakeLists.txt2
-rw-r--r--indra/llcorehttp/_httplibcurl.cpp1
-rw-r--r--indra/llcorehttp/_httpoprequest.cpp45
-rw-r--r--indra/llcorehttp/_httppolicy.cpp4
-rw-r--r--indra/llcorehttp/_httppolicy.h10
-rw-r--r--indra/llcorehttp/_httpservice.h8
-rw-r--r--indra/llcorehttp/httpcommon.cpp5
-rw-r--r--indra/llcorehttp/httpcommon.h11
-rw-r--r--indra/llcorehttp/httprequest.cpp13
-rw-r--r--indra/llcorehttp/httprequest.h16
10 files changed, 93 insertions, 22 deletions
diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt
index 9a073eb850..3fda524ddf 100644
--- a/indra/llcorehttp/CMakeLists.txt
+++ b/indra/llcorehttp/CMakeLists.txt
@@ -33,6 +33,7 @@ set(llcorehttp_SOURCE_FILES
_httpoprequest.cpp
_httpopsetpriority.cpp
_httppolicy.cpp
+ _httppolicyglobal.cpp
_httpreplyqueue.cpp
_httprequestqueue.cpp
_httpservice.cpp
@@ -55,6 +56,7 @@ set(llcorehttp_HEADER_FILES
_httpoprequest.h
_httpopsetpriority.h
_httppolicy.h
+ _httppolicyglobal.h
_httpreadyqueue.h
_httpreplyqueue.h
_httprequestqueue.h
diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp
index 704f9baac9..5272c391e8 100644
--- a/indra/llcorehttp/_httplibcurl.cpp
+++ b/indra/llcorehttp/_httplibcurl.cpp
@@ -27,6 +27,7 @@
#include "_httplibcurl.h"
#include "httpheaders.h"
+#include "bufferarray.h"
#include "_httpoprequest.h"
diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp
index f52ff5a44c..4bdc4a5257 100644
--- a/indra/llcorehttp/_httpoprequest.cpp
+++ b/indra/llcorehttp/_httpoprequest.cpp
@@ -40,8 +40,10 @@
#include "_httpreplyqueue.h"
#include "_httpservice.h"
#include "_httppolicy.h"
+#include "_httppolicyglobal.h"
#include "_httplibcurl.h"
+#include "llhttpstatuscodes.h"
namespace
{
@@ -153,14 +155,14 @@ HttpOpRequest::~HttpOpRequest()
void HttpOpRequest::stageFromRequest(HttpService * service)
{
addRef();
- service->getPolicy()->addOp(this); // transfers refcount
+ service->getPolicy().addOp(this); // transfers refcount
}
void HttpOpRequest::stageFromReady(HttpService * service)
{
addRef();
- service->getTransport()->addOp(this); // transfers refcount
+ service->getTransport().addOp(this); // transfers refcount
}
@@ -195,6 +197,8 @@ void HttpOpRequest::stageFromActive(HttpService * service)
void HttpOpRequest::visitNotifier(HttpRequest * request)
{
+ static const HttpStatus partial_content(HTTP_PARTIAL_CONTENT, HE_SUCCESS);
+
if (mLibraryHandler)
{
HttpResponse * response = new HttpResponse();
@@ -208,9 +212,15 @@ void HttpOpRequest::visitNotifier(HttpRequest * request)
offset = mReplyOffset;
length = mReplyLength;
}
- else if (mReplyBody)
+ else if (mReplyBody && partial_content == mStatus)
{
- // Provide implicit offset/length from request/response
+ // Legacy grid services did not provide a 'Content-Range'
+ // header in responses to full- or partly-satisfyiable
+ // 'Range' requests. For these, we have to hope that
+ // the data starts where requested and the length is simply
+ // whatever we received. A bit of sanity could be provided
+ // by overlapping ranged requests and verifying that the
+ // overlap matches.
offset = mReqOffset;
length = mReplyBody->size();
}
@@ -306,6 +316,9 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
// *FIXME: better error handling later
HttpStatus status;
+ // Get policy options
+ HttpPolicyGlobal & policy(service->getPolicy().getGlobalOptions());
+
mCurlHandle = curl_easy_init();
// curl_easy_setopt(mCurlHandle, CURLOPT_VERBOSE, 1);
curl_easy_setopt(mCurlHandle, CURLOPT_TIMEOUT, 30);
@@ -322,21 +335,40 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, 0);
curl_easy_setopt(mCurlHandle, CURLOPT_AUTOREFERER, 1);
curl_easy_setopt(mCurlHandle, CURLOPT_FOLLOWLOCATION, 1);
- curl_easy_setopt(mCurlHandle, CURLOPT_MAXREDIRS, 10);
+ curl_easy_setopt(mCurlHandle, CURLOPT_MAXREDIRS, 10); // *FIXME: parameterize this later
curl_easy_setopt(mCurlHandle, CURLOPT_WRITEFUNCTION, writeCallback);
curl_easy_setopt(mCurlHandle, CURLOPT_WRITEDATA, mCurlHandle);
curl_easy_setopt(mCurlHandle, CURLOPT_READFUNCTION, readCallback);
curl_easy_setopt(mCurlHandle, CURLOPT_READDATA, mCurlHandle);
+ curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYPEER, 1);
+ curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYHOST, 0);
+ std::string opt_value;
+ if (policy.get(HttpRequest::GP_CA_PATH, opt_value))
+ {
+ curl_easy_setopt(mCurlHandle, CURLOPT_CAPATH, opt_value.c_str());
+ }
+ if (policy.get(HttpRequest::GP_CA_FILE, opt_value))
+ {
+ curl_easy_setopt(mCurlHandle, CURLOPT_CAINFO, opt_value.c_str());
+ }
+ if (policy.get(HttpRequest::GP_HTTP_PROXY, opt_value))
+ {
+ curl_easy_setopt(mCurlHandle, CURLOPT_PROXY, opt_value.c_str());
+ }
+
switch (mReqMethod)
{
case HOR_GET:
curl_easy_setopt(mCurlHandle, CURLOPT_HTTPGET, 1);
+ mCurlHeaders = curl_slist_append(mCurlHeaders, "Connection: keep-alive");
+ mCurlHeaders = curl_slist_append(mCurlHeaders, "Keep-alive: 300");
break;
case HOR_POST:
{
curl_easy_setopt(mCurlHandle, CURLOPT_POST, 1);
+ curl_easy_setopt(mCurlHandle, CURLOPT_ENCODING, "");
long data_size(0);
if (mReqBody)
{
@@ -358,8 +390,11 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
data_size = mReqBody->size();
}
curl_easy_setopt(mCurlHandle, CURLOPT_INFILESIZE, data_size);
+ curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDS, (void *) NULL);
mCurlHeaders = curl_slist_append(mCurlHeaders, "Transfer-Encoding: chunked");
mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:");
+ mCurlHeaders = curl_slist_append(mCurlHeaders, "Connection: keep-alive");
+ mCurlHeaders = curl_slist_append(mCurlHeaders, "Keep-alive: 300");
}
break;
diff --git a/indra/llcorehttp/_httppolicy.cpp b/indra/llcorehttp/_httppolicy.cpp
index 1d28f23d56..51f5e487dc 100644
--- a/indra/llcorehttp/_httppolicy.cpp
+++ b/indra/llcorehttp/_httppolicy.cpp
@@ -76,12 +76,12 @@ void HttpPolicy::addOp(HttpOpRequest * op)
HttpService::ELoopSpeed HttpPolicy::processReadyQueue()
{
HttpService::ELoopSpeed result(HttpService::REQUEST_SLEEP);
- HttpLibcurl * pTransport(mService->getTransport());
+ HttpLibcurl & transport(mService->getTransport());
for (int policy_class(0); policy_class < HttpRequest::POLICY_CLASS_LIMIT; ++policy_class)
{
HttpReadyQueue & readyq(mReadyQueue[policy_class]);
- int active(pTransport->getActiveCountInClass(policy_class));
+ int active(transport.getActiveCountInClass(policy_class));
int needed(8 - active);
if (needed > 0 && mReadyInClass[policy_class] > 0)
diff --git a/indra/llcorehttp/_httppolicy.h b/indra/llcorehttp/_httppolicy.h
index 2bc03c531f..425079ec63 100644
--- a/indra/llcorehttp/_httppolicy.h
+++ b/indra/llcorehttp/_httppolicy.h
@@ -31,6 +31,7 @@
#include "httprequest.h"
#include "_httpservice.h"
#include "_httpreadyqueue.h"
+#include "_httppolicyglobal.h"
namespace LLCore
@@ -68,11 +69,20 @@ public:
// Shadows HttpService's method
bool changePriority(HttpHandle handle, HttpRequest::priority_t priority);
+
+ // Get pointer to global policy options. Caller is expected
+ // to do context checks like no setting once running.
+ HttpPolicyGlobal & getGlobalOptions()
+ {
+ return mGlobalOptions;
+ }
+
protected:
int mReadyInClass[HttpRequest::POLICY_CLASS_LIMIT];
HttpReadyQueue mReadyQueue[HttpRequest::POLICY_CLASS_LIMIT];
HttpService * mService; // Naked pointer, not refcounted, not owner
+ HttpPolicyGlobal mGlobalOptions;
}; // end class HttpPolicy
diff --git a/indra/llcorehttp/_httpservice.h b/indra/llcorehttp/_httpservice.h
index 095316c8a7..748354a8e4 100644
--- a/indra/llcorehttp/_httpservice.h
+++ b/indra/llcorehttp/_httpservice.h
@@ -148,14 +148,14 @@ public:
/// Threading: callable by worker thread.
bool changePriority(HttpHandle handle, HttpRequest::priority_t priority);
- HttpPolicy * getPolicy()
+ HttpPolicy & getPolicy()
{
- return mPolicy;
+ return *mPolicy;
}
- HttpLibcurl * getTransport()
+ HttpLibcurl & getTransport()
{
- return mTransport;
+ return *mTransport;
}
protected:
diff --git a/indra/llcorehttp/httpcommon.cpp b/indra/llcorehttp/httpcommon.cpp
index a01182cf23..9f17b5c842 100644
--- a/indra/llcorehttp/httpcommon.cpp
+++ b/indra/llcorehttp/httpcommon.cpp
@@ -66,7 +66,10 @@ std::string HttpStatus::toString() const
"Services shutting down",
"Operation canceled",
"Invalid Content-Range header encountered",
- "Request handle not found"
+ "Request handle not found",
+ "Invalid datatype for argument or option",
+ "Option has not been explicitly set",
+ "Option is not dynamic and must be set early"
};
static const int llcore_errors_count(sizeof(llcore_errors) / sizeof(llcore_errors[0]));
diff --git a/indra/llcorehttp/httpcommon.h b/indra/llcorehttp/httpcommon.h
index c01a5f85d3..fd2661b700 100644
--- a/indra/llcorehttp/httpcommon.h
+++ b/indra/llcorehttp/httpcommon.h
@@ -137,7 +137,16 @@ enum HttpError
HE_INV_CONTENT_RANGE_HDR = 4,
// Request handle not found
- HE_HANDLE_NOT_FOUND = 5
+ HE_HANDLE_NOT_FOUND = 5,
+
+ // Invalid datatype for option/setting
+ HE_INVALID_ARG = 6,
+
+ // Option hasn't been explicitly set
+ HE_OPT_NOT_SET = 7,
+
+ // Option not dynamic, must be set during init phase
+ HE_OPT_NOT_DYNAMIC = 8
}; // end enum HttpError
diff --git a/indra/llcorehttp/httprequest.cpp b/indra/llcorehttp/httprequest.cpp
index 0e512d97ed..baa0fe1a84 100644
--- a/indra/llcorehttp/httprequest.cpp
+++ b/indra/llcorehttp/httprequest.cpp
@@ -29,6 +29,7 @@
#include "_httprequestqueue.h"
#include "_httpreplyqueue.h"
#include "_httpservice.h"
+#include "_httppolicy.h"
#include "_httpoperation.h"
#include "_httpoprequest.h"
#include "_httpopsetpriority.h"
@@ -127,9 +128,17 @@ HttpRequest::~HttpRequest()
HttpStatus HttpRequest::setPolicyGlobalOption(EGlobalPolicy opt, long value)
{
- HttpStatus status;
+ // *FIXME: Fail if thread is running.
- return status;
+ return HttpService::instanceOf()->getPolicy().getGlobalOptions().set(opt, value);
+}
+
+
+HttpStatus HttpRequest::setPolicyGlobalOption(EGlobalPolicy opt, const std::string & value)
+{
+ // *FIXME: Fail if thread is running.
+
+ return HttpService::instanceOf()->getPolicy().getGlobalOptions().set(opt, value);
}
diff --git a/indra/llcorehttp/httprequest.h b/indra/llcorehttp/httprequest.h
index 57d2da245b..3592d5c6a3 100644
--- a/indra/llcorehttp/httprequest.h
+++ b/indra/llcorehttp/httprequest.h
@@ -111,7 +111,10 @@ public:
/// Maximum number of connections the library will use to
/// perform operations. This is somewhat soft as the underlying
/// transport will cache some connections (up to 5).
- GLOBAL_CONNECTION_LIMIT
+ GP_CONNECTION_LIMIT, ///< Takes long giving number of connections
+ GP_CA_PATH, ///< System path/directory where SSL certs are stored.
+ GP_CA_FILE, ///< System path/file containing certs.
+ GP_HTTP_PROXY ///< String giving host/port to use for HTTP proxy
};
/// Set a parameter on a global policy option. Calls
@@ -122,6 +125,7 @@ public:
/// @param value Desired value of option.
/// @return Standard status code.
HttpStatus setPolicyGlobalOption(EGlobalPolicy opt, long value);
+ HttpStatus setPolicyGlobalOption(EGlobalPolicy opt, const std::string & value);
/// Create a new policy class into which requests can be made.
///
@@ -134,15 +138,15 @@ public:
enum EClassPolicy
{
/// Limits the number of connections used for the class.
- CLASS_CONNECTION_LIMIT,
+ CP_CONNECTION_LIMIT,
/// Limits the number of connections used for a single
/// literal address/port pair within the class.
- PER_HOST_CONNECTION_LIMIT,
+ CP_PER_HOST_CONNECTION_LIMIT,
/// Suitable requests are allowed to pipeline on their
/// connections when they ask for it.
- ENABLE_PIPELINING
+ CP_ENABLE_PIPELINING
};
/// Set a parameter on a class-based policy option. Calls
@@ -153,9 +157,7 @@ public:
/// @param opt Enum of option to be set.
/// @param value Desired value of option.
/// @return Standard status code.
- HttpStatus setPolicyClassOption(policy_t policy_id,
- EClassPolicy opt,
- long value);
+ HttpStatus setPolicyClassOption(policy_t policy_id, EClassPolicy opt, long value);
/// @}