Big comment and naming cleanup. Ready for prime-time.
Add to-do list to _httpinternal.h to guide anyone who wants to pitch in and help.master
parent
334ce2556f
commit
85e69b043b
|
|
@ -32,12 +32,65 @@
|
|||
// something wrong is probably happening.
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// General library to-do list
|
||||
//
|
||||
// - Implement policy classes. Structure is mostly there just didn't
|
||||
// need it for the first consumer.
|
||||
// - Consider Removing 'priority' from the request interface. Its use
|
||||
// in an always active class can lead to starvation of low-priority
|
||||
// requests. Requires coodination of priority values across all
|
||||
// components that share a class. Changing priority across threads
|
||||
// is slightly expensive (relative to gain) and hasn't been completely
|
||||
// implemented. And the major user of priority, texture fetches,
|
||||
// may not really need it.
|
||||
// - Set/get for global policy and policy classes is clumsy. Rework
|
||||
// it heading in a direction that allows for more dynamic behavior.
|
||||
// - Move HttpOpRequest::prepareRequest() to HttpLibcurl for the
|
||||
// pedantic.
|
||||
// - Update downloader and other long-duration services are going to
|
||||
// need a progress notification. Initial idea is to introduce a
|
||||
// 'repeating request' which can piggyback on another request and
|
||||
// persist until canceled or carrier completes. Current queue
|
||||
// structures allow an HttpOperation object to be enqueued
|
||||
// repeatedly, so...
|
||||
// - Investigate making c-ares' re-implementation of a resolver library
|
||||
// more resilient or more intelligent on Mac. Part of the DNS failure
|
||||
// lies in here. The mechanism also looks a little less dynamic
|
||||
// than needed in an environments where networking is changing.
|
||||
// - Global optimizations: 'borrowing' connections from other classes,
|
||||
// HTTP pipelining.
|
||||
// - Dynamic/control system stuff: detect problems and self-adjust.
|
||||
// This won't help in the face of the router problems we've looked
|
||||
// at, however. Detect starvation due to UDP activity and provide
|
||||
// feedback to it.
|
||||
//
|
||||
// Integration to-do list
|
||||
// - LLTextureFetch still needs a major refactor. The use of
|
||||
// LLQueuedThread makes it hard to inspect workers and do the
|
||||
// resource waiting we're now doing. Rebuild along simpler lines
|
||||
// some of which are suggested in new commentary at the top of
|
||||
// the main source file.
|
||||
// - Expand areas of usage eventually leading to the removal of LLCurl.
|
||||
// Rough order of expansion:
|
||||
// . Mesh fetch
|
||||
// . Avatar names
|
||||
// . Group membership lists
|
||||
// . Caps access in general
|
||||
// . 'The rest'
|
||||
// - Adapt texture cache, image decode and other image consumers to
|
||||
// the BufferArray model to reduce data copying. Alternatively,
|
||||
// adapt this library to something else.
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
|
||||
// If '1', internal ready queues will not order ready
|
||||
// requests by priority, instead it's first-come-first-served.
|
||||
// Reprioritization requests have the side-effect of then
|
||||
// putting the modified request at the back of the ready queue.
|
||||
|
||||
#define LLCORE_READY_QUEUE_IGNORES_PRIORITY 1
|
||||
#define LLCORE_HTTP_READY_QUEUE_IGNORES_PRIORITY 1
|
||||
|
||||
|
||||
namespace LLCore
|
||||
|
|
@ -45,48 +98,48 @@ namespace LLCore
|
|||
|
||||
// Maxium number of policy classes that can be defined.
|
||||
// *TODO: Currently limited to the default class, extend.
|
||||
const int POLICY_CLASS_LIMIT = 1;
|
||||
const int HTTP_POLICY_CLASS_LIMIT = 1;
|
||||
|
||||
// Debug/informational tracing. Used both
|
||||
// as a global option and in per-request traces.
|
||||
const int TRACE_OFF = 0;
|
||||
const int TRACE_LOW = 1;
|
||||
const int TRACE_CURL_HEADERS = 2;
|
||||
const int TRACE_CURL_BODIES = 3;
|
||||
const int HTTP_TRACE_OFF = 0;
|
||||
const int HTTP_TRACE_LOW = 1;
|
||||
const int HTTP_TRACE_CURL_HEADERS = 2;
|
||||
const int HTTP_TRACE_CURL_BODIES = 3;
|
||||
|
||||
const int TRACE_MIN = TRACE_OFF;
|
||||
const int TRACE_MAX = TRACE_CURL_BODIES;
|
||||
const int HTTP_TRACE_MIN = HTTP_TRACE_OFF;
|
||||
const int HTTP_TRACE_MAX = HTTP_TRACE_CURL_BODIES;
|
||||
|
||||
// Request retry limits
|
||||
const int DEFAULT_RETRY_COUNT = 5;
|
||||
const int LIMIT_RETRY_MIN = 0;
|
||||
const int LIMIT_RETRY_MAX = 100;
|
||||
const int HTTP_RETRY_COUNT_DEFAULT = 5;
|
||||
const int HTTP_RETRY_COUNT_MIN = 0;
|
||||
const int HTTP_RETRY_COUNT_MAX = 100;
|
||||
|
||||
const int DEFAULT_HTTP_REDIRECTS = 10;
|
||||
const int HTTP_REDIRECTS_DEFAULT = 10;
|
||||
|
||||
// Timeout value used for both connect and protocol exchange.
|
||||
// Retries and time-on-queue are not included and aren't
|
||||
// accounted for.
|
||||
const long DEFAULT_TIMEOUT = 30L;
|
||||
const long LIMIT_TIMEOUT_MIN = 0L;
|
||||
const long LIMIT_TIMEOUT_MAX = 3600L;
|
||||
const long HTTP_REQUEST_TIMEOUT_DEFAULT = 30L;
|
||||
const long HTTP_REQUEST_TIMEOUT_MIN = 0L;
|
||||
const long HTTP_REQUEST_TIMEOUT_MAX = 3600L;
|
||||
|
||||
// Limits on connection counts
|
||||
const int DEFAULT_CONNECTIONS = 8;
|
||||
const int LIMIT_CONNECTIONS_MIN = 1;
|
||||
const int LIMIT_CONNECTIONS_MAX = 256;
|
||||
const int HTTP_CONNECTION_LIMIT_DEFAULT = 8;
|
||||
const int HTTP_CONNECTION_LIMIT_MIN = 1;
|
||||
const int HTTP_CONNECTION_LIMIT_MAX = 256;
|
||||
|
||||
// Tuning parameters
|
||||
|
||||
// Time worker thread sleeps after a pass through the
|
||||
// request, ready and active queues.
|
||||
const int LOOP_SLEEP_NORMAL_MS = 2;
|
||||
const int HTTP_SERVICE_LOOP_SLEEP_NORMAL_MS = 2;
|
||||
|
||||
// Block allocation size (a tuning parameter) is found
|
||||
// in bufferarray.h.
|
||||
|
||||
// Compatibility controls
|
||||
const bool ENABLE_LINKSYS_WRT54G_V5_DNS_FIX = true;
|
||||
const bool HTTP_ENABLE_LINKSYS_WRT54G_V5_DNS_FIX = true;
|
||||
|
||||
} // end namespace LLCore
|
||||
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ void HttpLibcurl::shutdown()
|
|||
|
||||
void HttpLibcurl::start(int policy_count)
|
||||
{
|
||||
llassert_always(policy_count <= POLICY_CLASS_LIMIT);
|
||||
llassert_always(policy_count <= HTTP_POLICY_CLASS_LIMIT);
|
||||
llassert_always(! mMultiHandles); // One-time call only
|
||||
|
||||
mPolicyCount = policy_count;
|
||||
|
|
@ -156,6 +156,7 @@ HttpService::ELoopSpeed HttpLibcurl::processTransport()
|
|||
}
|
||||
|
||||
|
||||
// Caller has provided us with a ref count on op.
|
||||
void HttpLibcurl::addOp(HttpOpRequest * op)
|
||||
{
|
||||
llassert_always(op->mReqPolicy < mPolicyCount);
|
||||
|
|
@ -165,7 +166,7 @@ void HttpLibcurl::addOp(HttpOpRequest * op)
|
|||
if (! op->prepareRequest(mService))
|
||||
{
|
||||
// Couldn't issue request, fail with notification
|
||||
// *FIXME: Need failure path
|
||||
// *TODO: Need failure path
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -173,7 +174,7 @@ void HttpLibcurl::addOp(HttpOpRequest * op)
|
|||
curl_multi_add_handle(mMultiHandles[op->mReqPolicy], op->mCurlHandle);
|
||||
op->mCurlActive = true;
|
||||
|
||||
if (op->mTracing > TRACE_OFF)
|
||||
if (op->mTracing > HTTP_TRACE_OFF)
|
||||
{
|
||||
HttpPolicy & policy(mService->getPolicy());
|
||||
|
||||
|
|
@ -215,7 +216,7 @@ bool HttpLibcurl::cancel(HttpHandle handle)
|
|||
|
||||
// *NOTE: cancelRequest logic parallels completeRequest logic.
|
||||
// Keep them synchronized as necessary. Caller is expected to
|
||||
// remove to op from the active list and release the op *after*
|
||||
// remove the op from the active list and release the op *after*
|
||||
// calling this method. It must be called first to deliver the
|
||||
// op to the reply queue with refcount intact.
|
||||
void HttpLibcurl::cancelRequest(HttpOpRequest * op)
|
||||
|
|
@ -229,7 +230,7 @@ void HttpLibcurl::cancelRequest(HttpOpRequest * op)
|
|||
op->mCurlHandle = NULL;
|
||||
|
||||
// Tracing
|
||||
if (op->mTracing > TRACE_OFF)
|
||||
if (op->mTracing > HTTP_TRACE_OFF)
|
||||
{
|
||||
LL_INFOS("CoreHttp") << "TRACE, RequestCanceled, Handle: "
|
||||
<< static_cast<HttpHandle>(op)
|
||||
|
|
@ -305,7 +306,7 @@ bool HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode
|
|||
op->mCurlHandle = NULL;
|
||||
|
||||
// Tracing
|
||||
if (op->mTracing > TRACE_OFF)
|
||||
if (op->mTracing > HTTP_TRACE_OFF)
|
||||
{
|
||||
LL_INFOS("CoreHttp") << "TRACE, RequestComplete, Handle: "
|
||||
<< static_cast<HttpHandle>(op)
|
||||
|
|
|
|||
|
|
@ -68,24 +68,41 @@ public:
|
|||
/// Give cycles to libcurl to run active requests. Completed
|
||||
/// operations (successful or failed) will be retried or handed
|
||||
/// over to the reply queue as final responses.
|
||||
///
|
||||
/// @return Indication of how long this method is
|
||||
/// willing to wait for next service call.
|
||||
HttpService::ELoopSpeed processTransport();
|
||||
|
||||
/// Add request to the active list. Caller is expected to have
|
||||
/// provided us with a reference count to hold the request. (No
|
||||
/// additional references will be added.)
|
||||
/// provided us with a reference count on the op to hold the
|
||||
/// request. (No additional references will be added.)
|
||||
void addOp(HttpOpRequest * op);
|
||||
|
||||
/// One-time call to set the number of policy classes to be
|
||||
/// serviced and to create the resources for each. Value
|
||||
/// must agree with HttpPolicy::setPolicies() call.
|
||||
void start(int policy_count);
|
||||
|
||||
|
||||
/// Synchronously stop libcurl operations. All active requests
|
||||
/// are canceled and removed from libcurl's handling. Easy
|
||||
/// handles are detached from their multi handles and released.
|
||||
/// Multi handles are also released. Canceled requests are
|
||||
/// completed with canceled status and made available on their
|
||||
/// respective reply queues.
|
||||
///
|
||||
/// Can be restarted with a start() call.
|
||||
void shutdown();
|
||||
|
||||
|
||||
/// Return global and per-class counts of active requests.
|
||||
int getActiveCount() const;
|
||||
int getActiveCountInClass(int policy_class) const;
|
||||
|
||||
// Shadows HttpService's method
|
||||
/// Attempt to cancel a request identified by handle.
|
||||
///
|
||||
/// Interface shadows HttpService's method.
|
||||
///
|
||||
/// @return True if handle was found and operation canceled.
|
||||
///
|
||||
bool cancel(HttpHandle handle);
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -26,18 +26,11 @@
|
|||
|
||||
#include "_httpopcancel.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <algorithm>
|
||||
|
||||
#include "httpcommon.h"
|
||||
#include "httphandler.h"
|
||||
#include "httpresponse.h"
|
||||
|
||||
#include "_httprequestqueue.h"
|
||||
#include "_httpreplyqueue.h"
|
||||
#include "_httpservice.h"
|
||||
#include "_httppolicy.h"
|
||||
#include "_httplibcurl.h"
|
||||
|
||||
|
||||
namespace LLCore
|
||||
|
|
|
|||
|
|
@ -46,11 +46,14 @@ namespace LLCore
|
|||
/// be canceled, if possible. This includes active requests
|
||||
/// that may be in the middle of an HTTP transaction. Any
|
||||
/// completed request will not be canceled and will return
|
||||
/// its final status unchanged.
|
||||
/// its final status unchanged and *this* request will complete
|
||||
/// with an HE_HANDLE_NOT_FOUND error status.
|
||||
|
||||
class HttpOpCancel : public HttpOperation
|
||||
{
|
||||
public:
|
||||
/// @param handle Handle of previously-issued request to
|
||||
/// be canceled.
|
||||
HttpOpCancel(HttpHandle handle);
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ void HttpOperation::stageFromRequest(HttpService *)
|
|||
// Default implementation should never be called. This
|
||||
// indicates an operation making a transition that isn't
|
||||
// defined.
|
||||
LL_ERRS("HttpCore") << "Default stateFromRequest method may not be called."
|
||||
LL_ERRS("HttpCore") << "Default stageFromRequest method may not be called."
|
||||
<< LL_ENDL;
|
||||
}
|
||||
|
||||
|
|
@ -104,7 +104,7 @@ void HttpOperation::stageFromReady(HttpService *)
|
|||
// Default implementation should never be called. This
|
||||
// indicates an operation making a transition that isn't
|
||||
// defined.
|
||||
LL_ERRS("HttpCore") << "Default stateFromReady method may not be called."
|
||||
LL_ERRS("HttpCore") << "Default stageFromReady method may not be called."
|
||||
<< LL_ENDL;
|
||||
}
|
||||
|
||||
|
|
@ -114,7 +114,7 @@ void HttpOperation::stageFromActive(HttpService *)
|
|||
// Default implementation should never be called. This
|
||||
// indicates an operation making a transition that isn't
|
||||
// defined.
|
||||
LL_ERRS("HttpCore") << "Default stateFromActive method may not be called."
|
||||
LL_ERRS("HttpCore") << "Default stageFromActive method may not be called."
|
||||
<< LL_ENDL;
|
||||
}
|
||||
|
||||
|
|
@ -143,7 +143,7 @@ HttpStatus HttpOperation::cancel()
|
|||
|
||||
void HttpOperation::addAsReply()
|
||||
{
|
||||
if (mTracing > TRACE_OFF)
|
||||
if (mTracing > HTTP_TRACE_OFF)
|
||||
{
|
||||
LL_INFOS("CoreHttp") << "TRACE, ToReplyQueue, Handle: "
|
||||
<< static_cast<HttpHandle>(this)
|
||||
|
|
|
|||
|
|
@ -72,9 +72,11 @@ class HttpService;
|
|||
class HttpOperation : public LLCoreInt::RefCounted
|
||||
{
|
||||
public:
|
||||
/// Threading: called by a consumer/application thread.
|
||||
HttpOperation();
|
||||
|
||||
protected:
|
||||
/// Threading: called by any thread.
|
||||
virtual ~HttpOperation(); // Use release()
|
||||
|
||||
private:
|
||||
|
|
@ -82,28 +84,87 @@ private:
|
|||
void operator=(const HttpOperation &); // Not defined
|
||||
|
||||
public:
|
||||
/// Register a reply queue and a handler for completion notifications.
|
||||
///
|
||||
/// Invokers of operations that want to receive notification that an
|
||||
/// operation has been completed do so by binding a reply queue and
|
||||
/// a handler object to the request.
|
||||
///
|
||||
/// @param reply_queue Pointer to the reply queue where completion
|
||||
/// notifications are to be queued (typically
|
||||
/// by addAsReply()). This will typically be
|
||||
/// the reply queue referenced by the request
|
||||
/// object. This method will increment the
|
||||
/// refcount on the queue holding the queue
|
||||
/// until delivery is complete. Using a reply_queue
|
||||
/// even if the handler is NULL has some benefits
|
||||
/// for memory deallocation by keeping it in the
|
||||
/// originating thread.
|
||||
///
|
||||
/// @param handler Possibly NULL pointer to a non-refcounted
|
||||
//// handler object to be invoked (onCompleted)
|
||||
/// when the operation is finished. Note that
|
||||
/// the handler object is never dereferenced
|
||||
/// by the worker thread. This is passible data
|
||||
/// until notification is performed.
|
||||
///
|
||||
/// Threading: called by application thread.
|
||||
///
|
||||
void setReplyPath(HttpReplyQueue * reply_queue,
|
||||
HttpHandler * handler);
|
||||
|
||||
HttpHandler * getUserHandler() const
|
||||
{
|
||||
return mUserHandler;
|
||||
}
|
||||
|
||||
/// The three possible staging steps in an operation's lifecycle.
|
||||
/// Asynchronous requests like HTTP operations move from the
|
||||
/// request queue to the ready queue via stageFromRequest. Then
|
||||
/// from the ready queue to the active queue by stageFromReady. And
|
||||
/// when complete, to the reply queue via stageFromActive and the
|
||||
/// addAsReply utility.
|
||||
///
|
||||
/// Immediate mode operations (everything else) move from the
|
||||
/// request queue to the reply queue directly via stageFromRequest
|
||||
/// and addAsReply with no existence on the ready or active queues.
|
||||
///
|
||||
/// These methods will take out a reference count on the request,
|
||||
/// caller only needs to dispose of its reference when done with
|
||||
/// the request.
|
||||
///
|
||||
/// Threading: called by worker thread.
|
||||
///
|
||||
virtual void stageFromRequest(HttpService *);
|
||||
virtual void stageFromReady(HttpService *);
|
||||
virtual void stageFromActive(HttpService *);
|
||||
|
||||
/// Delivers a notification to a handler object on completion.
|
||||
///
|
||||
/// Once a request is complete and it has been removed from its
|
||||
/// reply queue, a handler notification may be delivered by a
|
||||
/// call to HttpRequest::update(). This method does the necessary
|
||||
/// dispatching.
|
||||
///
|
||||
/// Threading: called by application thread.
|
||||
///
|
||||
virtual void visitNotifier(HttpRequest *);
|
||||
|
||||
|
||||
/// Cancels the operation whether queued or active.
|
||||
/// Final status of the request becomes canceled (an error) and
|
||||
/// that will be delivered to caller via notification scheme.
|
||||
///
|
||||
/// Threading: called by worker thread.
|
||||
///
|
||||
virtual HttpStatus cancel();
|
||||
|
||||
protected:
|
||||
/// Delivers request to reply queue on completion. After this
|
||||
/// call, worker thread no longer accesses the object and it
|
||||
/// is owned by the reply queue.
|
||||
///
|
||||
/// Threading: called by worker thread.
|
||||
///
|
||||
void addAsReply();
|
||||
|
||||
protected:
|
||||
HttpReplyQueue * mReplyQueue; // Have refcount
|
||||
HttpHandler * mUserHandler;
|
||||
HttpHandler * mUserHandler; // Naked pointer
|
||||
|
||||
public:
|
||||
// Request Data
|
||||
|
|
@ -172,7 +233,7 @@ public:
|
|||
|
||||
/// HttpOpSpin is a test-only request that puts the worker
|
||||
/// thread into a cpu spin. Used for unit tests and cleanup
|
||||
/// evaluation. You do not want to use this.
|
||||
/// evaluation. You do not want to use this in production.
|
||||
class HttpOpSpin : public HttpOperation
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -111,10 +111,10 @@ HttpOpRequest::HttpOpRequest()
|
|||
mReplyHeaders(NULL),
|
||||
mPolicyRetries(0),
|
||||
mPolicyRetryAt(HttpTime(0)),
|
||||
mPolicyRetryLimit(DEFAULT_RETRY_COUNT)
|
||||
mPolicyRetryLimit(HTTP_RETRY_COUNT_DEFAULT)
|
||||
{
|
||||
// *NOTE: As members are added, retry initialization/cleanup
|
||||
// may need to be extended in @prepareRequest().
|
||||
// may need to be extended in @see prepareRequest().
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -153,9 +153,6 @@ HttpOpRequest::~HttpOpRequest()
|
|||
mCurlHeaders = NULL;
|
||||
}
|
||||
|
||||
mReplyOffset = 0;
|
||||
mReplyLength = 0;
|
||||
mReplyFullLength = 0;
|
||||
if (mReplyBody)
|
||||
{
|
||||
mReplyBody->release();
|
||||
|
|
@ -215,8 +212,6 @@ void HttpOpRequest::stageFromActive(HttpService * service)
|
|||
|
||||
void HttpOpRequest::visitNotifier(HttpRequest * request)
|
||||
{
|
||||
static const HttpStatus partial_content(HTTP_PARTIAL_CONTENT, HE_SUCCESS);
|
||||
|
||||
if (mUserHandler)
|
||||
{
|
||||
HttpResponse * response = new HttpResponse();
|
||||
|
|
@ -339,8 +334,8 @@ void HttpOpRequest::setupCommon(HttpRequest::policy_t policy_id,
|
|||
mProcFlags |= PF_SAVE_HEADERS;
|
||||
}
|
||||
mPolicyRetryLimit = options->getRetries();
|
||||
mPolicyRetryLimit = llclamp(mPolicyRetryLimit, LIMIT_RETRY_MIN, LIMIT_RETRY_MAX);
|
||||
mTracing = (std::max)(mTracing, llclamp(options->getTrace(), TRACE_MIN, TRACE_MAX));
|
||||
mPolicyRetryLimit = llclamp(mPolicyRetryLimit, HTTP_RETRY_COUNT_MIN, HTTP_RETRY_COUNT_MAX);
|
||||
mTracing = (std::max)(mTracing, llclamp(options->getTrace(), HTTP_TRACE_MIN, HTTP_TRACE_MAX));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -394,7 +389,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
curl_easy_setopt(mCurlHandle, CURLOPT_PRIVATE, this);
|
||||
curl_easy_setopt(mCurlHandle, CURLOPT_ENCODING, "");
|
||||
|
||||
if (ENABLE_LINKSYS_WRT54G_V5_DNS_FIX)
|
||||
if (HTTP_ENABLE_LINKSYS_WRT54G_V5_DNS_FIX)
|
||||
{
|
||||
// The Linksys WRT54G V5 router has an issue with frequent
|
||||
// DNS lookups from LAN machines. If they happen too often,
|
||||
|
|
@ -402,7 +397,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
// about 700 or so requests and starts issuing TCP RSTs to
|
||||
// new connections. Reuse the DNS lookups for even a few
|
||||
// seconds and no RSTs.
|
||||
curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, 10);
|
||||
curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, 15);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -414,7 +409,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
}
|
||||
curl_easy_setopt(mCurlHandle, CURLOPT_AUTOREFERER, 1);
|
||||
curl_easy_setopt(mCurlHandle, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_easy_setopt(mCurlHandle, CURLOPT_MAXREDIRS, DEFAULT_HTTP_REDIRECTS);
|
||||
curl_easy_setopt(mCurlHandle, CURLOPT_MAXREDIRS, HTTP_REDIRECTS_DEFAULT);
|
||||
curl_easy_setopt(mCurlHandle, CURLOPT_WRITEFUNCTION, writeCallback);
|
||||
curl_easy_setopt(mCurlHandle, CURLOPT_WRITEDATA, this);
|
||||
curl_easy_setopt(mCurlHandle, CURLOPT_READFUNCTION, readCallback);
|
||||
|
|
@ -434,7 +429,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
}
|
||||
else if (policy.get(HttpRequest::GP_HTTP_PROXY, &opt_value))
|
||||
{
|
||||
// *TODO: This is fine for now but get fuller socks/
|
||||
// *TODO: This is fine for now but get fuller socks5/
|
||||
// authentication thing going later....
|
||||
curl_easy_setopt(mCurlHandle, CURLOPT_PROXY, opt_value->c_str());
|
||||
curl_easy_setopt(mCurlHandle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
|
||||
|
|
@ -497,7 +492,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
}
|
||||
|
||||
// Tracing
|
||||
if (mTracing >= TRACE_CURL_HEADERS)
|
||||
if (mTracing >= HTTP_TRACE_CURL_HEADERS)
|
||||
{
|
||||
curl_easy_setopt(mCurlHandle, CURLOPT_VERBOSE, 1);
|
||||
curl_easy_setopt(mCurlHandle, CURLOPT_DEBUGDATA, this);
|
||||
|
|
@ -528,11 +523,11 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
mCurlHeaders = curl_slist_append(mCurlHeaders, "Pragma:");
|
||||
|
||||
// Request options
|
||||
long timeout(DEFAULT_TIMEOUT);
|
||||
long timeout(HTTP_REQUEST_TIMEOUT_DEFAULT);
|
||||
if (mReqOptions)
|
||||
{
|
||||
timeout = mReqOptions->getTimeout();
|
||||
timeout = llclamp(timeout, LIMIT_TIMEOUT_MIN, LIMIT_TIMEOUT_MAX);
|
||||
timeout = llclamp(timeout, HTTP_REQUEST_TIMEOUT_MIN, HTTP_REQUEST_TIMEOUT_MAX);
|
||||
}
|
||||
curl_easy_setopt(mCurlHandle, CURLOPT_TIMEOUT, timeout);
|
||||
curl_easy_setopt(mCurlHandle, CURLOPT_CONNECTTIMEOUT, timeout);
|
||||
|
|
@ -605,12 +600,6 @@ size_t HttpOpRequest::headerCallback(void * data, size_t size, size_t nmemb, voi
|
|||
static const char con_ran_line[] = "content-range:";
|
||||
static const size_t con_ran_line_len = sizeof(con_ran_line) - 1;
|
||||
|
||||
static const char con_type_line[] = "content-type:";
|
||||
static const size_t con_type_line_len = sizeof(con_type_line) - 1;
|
||||
|
||||
static const char con_enc_line[] = "content-encoding:";
|
||||
static const size_t con_enc_line_len = sizeof(con_enc_line) - 1;
|
||||
|
||||
HttpOpRequest * op(static_cast<HttpOpRequest *>(userdata));
|
||||
|
||||
const size_t hdr_size(size * nmemb);
|
||||
|
|
@ -705,7 +694,7 @@ int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffe
|
|||
switch (info)
|
||||
{
|
||||
case CURLINFO_TEXT:
|
||||
if (op->mTracing >= TRACE_CURL_HEADERS)
|
||||
if (op->mTracing >= HTTP_TRACE_CURL_HEADERS)
|
||||
{
|
||||
tag = "TEXT";
|
||||
escape_libcurl_debug_data(buffer, len, true, safe_line);
|
||||
|
|
@ -714,7 +703,7 @@ int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffe
|
|||
break;
|
||||
|
||||
case CURLINFO_HEADER_IN:
|
||||
if (op->mTracing >= TRACE_CURL_HEADERS)
|
||||
if (op->mTracing >= HTTP_TRACE_CURL_HEADERS)
|
||||
{
|
||||
tag = "HEADERIN";
|
||||
escape_libcurl_debug_data(buffer, len, true, safe_line);
|
||||
|
|
@ -723,7 +712,7 @@ int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffe
|
|||
break;
|
||||
|
||||
case CURLINFO_HEADER_OUT:
|
||||
if (op->mTracing >= TRACE_CURL_HEADERS)
|
||||
if (op->mTracing >= HTTP_TRACE_CURL_HEADERS)
|
||||
{
|
||||
tag = "HEADEROUT";
|
||||
escape_libcurl_debug_data(buffer, 2 * len, true, safe_line); // Goes out as one line
|
||||
|
|
@ -732,11 +721,11 @@ int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffe
|
|||
break;
|
||||
|
||||
case CURLINFO_DATA_IN:
|
||||
if (op->mTracing >= TRACE_CURL_HEADERS)
|
||||
if (op->mTracing >= HTTP_TRACE_CURL_HEADERS)
|
||||
{
|
||||
tag = "DATAIN";
|
||||
logit = true;
|
||||
if (op->mTracing >= TRACE_CURL_BODIES)
|
||||
if (op->mTracing >= HTTP_TRACE_CURL_BODIES)
|
||||
{
|
||||
escape_libcurl_debug_data(buffer, len, false, safe_line);
|
||||
}
|
||||
|
|
@ -750,11 +739,11 @@ int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffe
|
|||
break;
|
||||
|
||||
case CURLINFO_DATA_OUT:
|
||||
if (op->mTracing >= TRACE_CURL_HEADERS)
|
||||
if (op->mTracing >= HTTP_TRACE_CURL_HEADERS)
|
||||
{
|
||||
tag = "DATAOUT";
|
||||
logit = true;
|
||||
if (op->mTracing >= TRACE_CURL_BODIES)
|
||||
if (op->mTracing >= HTTP_TRACE_CURL_BODIES)
|
||||
{
|
||||
escape_libcurl_debug_data(buffer, len, false, safe_line);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,7 +88,14 @@ public:
|
|||
virtual void visitNotifier(HttpRequest * request);
|
||||
|
||||
public:
|
||||
// Setup Methods
|
||||
/// Setup Methods
|
||||
///
|
||||
/// Basically an RPC setup for each type of HTTP method
|
||||
/// invocation with one per method type. These are
|
||||
/// generally invoked right after construction.
|
||||
///
|
||||
/// Threading: called by application thread
|
||||
///
|
||||
HttpStatus setupGet(HttpRequest::policy_t policy_id,
|
||||
HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
|
|
@ -116,19 +123,32 @@ public:
|
|||
BufferArray * body,
|
||||
HttpOptions * options,
|
||||
HttpHeaders * headers);
|
||||
|
||||
|
||||
// Internal method used to setup the libcurl options for a request.
|
||||
// Does all the libcurl handle setup in one place.
|
||||
//
|
||||
// Threading: called by worker thread
|
||||
//
|
||||
HttpStatus prepareRequest(HttpService * service);
|
||||
|
||||
virtual HttpStatus cancel();
|
||||
|
||||
protected:
|
||||
// Common setup for all the request methods.
|
||||
//
|
||||
// Threading: called by application thread
|
||||
//
|
||||
void setupCommon(HttpRequest::policy_t policy_id,
|
||||
HttpRequest::priority_t priority,
|
||||
const std::string & url,
|
||||
BufferArray * body,
|
||||
HttpOptions * options,
|
||||
HttpHeaders * headers);
|
||||
|
||||
|
||||
// libcurl operational callbacks
|
||||
//
|
||||
// Threading: called by worker thread
|
||||
//
|
||||
static size_t writeCallback(void * data, size_t size, size_t nmemb, void * userdata);
|
||||
static size_t readCallback(void * data, size_t size, size_t nmemb, void * userdata);
|
||||
static size_t headerCallback(void * data, size_t size, size_t nmemb, void * userdata);
|
||||
|
|
|
|||
|
|
@ -26,18 +26,10 @@
|
|||
|
||||
#include "_httpopsetget.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <algorithm>
|
||||
|
||||
#include "httpcommon.h"
|
||||
#include "httphandler.h"
|
||||
#include "httpresponse.h"
|
||||
|
||||
#include "_httprequestqueue.h"
|
||||
#include "_httpreplyqueue.h"
|
||||
#include "_httpservice.h"
|
||||
#include "_httppolicy.h"
|
||||
#include "_httplibcurl.h"
|
||||
|
||||
|
||||
namespace LLCore
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ namespace LLCore
|
|||
|
||||
/// HttpOpSetGet requests dynamic changes to policy and
|
||||
/// configuration settings.
|
||||
///
|
||||
/// *NOTE: Expect this to change. Don't really like it yet.
|
||||
|
||||
class HttpOpSetGet : public HttpOperation
|
||||
{
|
||||
|
|
@ -58,6 +60,7 @@ private:
|
|||
void operator=(const HttpOpSetGet &); // Not defined
|
||||
|
||||
public:
|
||||
/// Threading: called by application thread
|
||||
void setupGet(HttpRequest::EGlobalPolicy setting);
|
||||
void setupSet(HttpRequest::EGlobalPolicy setting, const std::string & value);
|
||||
|
||||
|
|
|
|||
|
|
@ -40,12 +40,17 @@ namespace LLCore
|
|||
{
|
||||
|
||||
|
||||
// Per-policy-class data for a running system.
|
||||
// Collection of queues, parameters, history, metrics, etc.
|
||||
// for a single policy class.
|
||||
//
|
||||
// Threading: accessed only by worker thread
|
||||
struct HttpPolicy::State
|
||||
{
|
||||
public:
|
||||
State()
|
||||
: mConnMax(DEFAULT_CONNECTIONS),
|
||||
mConnAt(DEFAULT_CONNECTIONS),
|
||||
: mConnMax(HTTP_CONNECTION_LIMIT_DEFAULT),
|
||||
mConnAt(HTTP_CONNECTION_LIMIT_DEFAULT),
|
||||
mConnMin(1),
|
||||
mNextSample(0),
|
||||
mErrorCount(0),
|
||||
|
|
@ -298,6 +303,7 @@ bool HttpPolicy::cancel(HttpHandle handle)
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool HttpPolicy::stageAfterCompletion(HttpOpRequest * op)
|
||||
{
|
||||
static const HttpStatus cant_connect(HttpStatus::EXT_CURL_EASY, CURLE_COULDNT_CONNECT);
|
||||
|
|
@ -345,7 +351,7 @@ bool HttpPolicy::stageAfterCompletion(HttpOpRequest * op)
|
|||
}
|
||||
|
||||
|
||||
int HttpPolicy::getReadyCount(HttpRequest::policy_t policy_class)
|
||||
int HttpPolicy::getReadyCount(HttpRequest::policy_t policy_class) const
|
||||
{
|
||||
if (policy_class < mActiveClasses)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -63,22 +63,37 @@ public:
|
|||
/// Cancel all ready and retry requests sending them to
|
||||
/// their notification queues. Release state resources
|
||||
/// making further request handling impossible.
|
||||
///
|
||||
/// Threading: called by worker thread
|
||||
void shutdown();
|
||||
|
||||
/// Deliver policy definitions and enable handling of
|
||||
/// requests. One-time call invoked before starting
|
||||
/// the worker thread.
|
||||
///
|
||||
/// Threading: called by application thread
|
||||
void start(const HttpPolicyGlobal & global,
|
||||
const std::vector<HttpPolicyClass> & classes);
|
||||
|
||||
/// Give the policy layer some cycles to scan the ready
|
||||
/// queue promoting higher-priority requests to active
|
||||
/// as permited.
|
||||
///
|
||||
/// @return Indication of how soon this method
|
||||
/// should be called again.
|
||||
///
|
||||
/// Threading: called by worker thread
|
||||
HttpService::ELoopSpeed processReadyQueue();
|
||||
|
||||
/// Add request to a ready queue. Caller is expected to have
|
||||
/// provided us with a reference count to hold the request. (No
|
||||
/// additional references will be added.)
|
||||
///
|
||||
/// OpRequest is owned by the request queue after this call
|
||||
/// and should not be modified by anyone until retrieved
|
||||
/// from queue.
|
||||
///
|
||||
/// Threading: called by any thread
|
||||
void addOp(HttpOpRequest *);
|
||||
|
||||
/// Similar to addOp, used when a caller wants to retry a
|
||||
|
|
@ -87,12 +102,20 @@ public:
|
|||
/// handling is the same and retried operations are considered
|
||||
/// before new ones but that doesn't guarantee completion
|
||||
/// order.
|
||||
///
|
||||
/// Threading: called by worker thread
|
||||
void retryOp(HttpOpRequest *);
|
||||
|
||||
// Shadows HttpService's method
|
||||
/// Attempt to change the priority of an earlier request.
|
||||
/// Request that Shadows HttpService's method
|
||||
///
|
||||
/// Threading: called by worker thread
|
||||
bool changePriority(HttpHandle handle, HttpRequest::priority_t priority);
|
||||
|
||||
// Shadows HttpService's method as well
|
||||
/// Attempt to cancel a previous request.
|
||||
/// Shadows HttpService's method as well
|
||||
///
|
||||
/// Threading: called by worker thread
|
||||
bool cancel(HttpHandle handle);
|
||||
|
||||
/// When transport is finished with an op and takes it off the
|
||||
|
|
@ -103,17 +126,25 @@ public:
|
|||
/// @return Returns true of the request is still active
|
||||
/// or ready after staging, false if has been
|
||||
/// sent on to the reply queue.
|
||||
///
|
||||
/// Threading: called by worker thread
|
||||
bool stageAfterCompletion(HttpOpRequest * op);
|
||||
|
||||
// Get pointer to global policy options. Caller is expected
|
||||
// to do context checks like no setting once running.
|
||||
///
|
||||
/// Threading: called by any thread *but* the object may
|
||||
/// only be modified by the worker thread once running.
|
||||
///
|
||||
HttpPolicyGlobal & getGlobalOptions()
|
||||
{
|
||||
return mGlobalOptions;
|
||||
}
|
||||
|
||||
// Get ready counts for a particular class
|
||||
int getReadyCount(HttpRequest::policy_t policy_class);
|
||||
/// Get ready counts for a particular policy class
|
||||
///
|
||||
/// Threading: called by worker thread
|
||||
int getReadyCount(HttpRequest::policy_t policy_class) const;
|
||||
|
||||
protected:
|
||||
struct State;
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ namespace LLCore
|
|||
|
||||
HttpPolicyClass::HttpPolicyClass()
|
||||
: mSetMask(0UL),
|
||||
mConnectionLimit(DEFAULT_CONNECTIONS),
|
||||
mPerHostConnectionLimit(DEFAULT_CONNECTIONS),
|
||||
mConnectionLimit(HTTP_CONNECTION_LIMIT_DEFAULT),
|
||||
mPerHostConnectionLimit(HTTP_CONNECTION_LIMIT_DEFAULT),
|
||||
mPipelining(0)
|
||||
{}
|
||||
|
||||
|
|
@ -71,11 +71,11 @@ HttpStatus HttpPolicyClass::set(HttpRequest::EClassPolicy opt, long value)
|
|||
switch (opt)
|
||||
{
|
||||
case HttpRequest::CP_CONNECTION_LIMIT:
|
||||
mConnectionLimit = llclamp(value, long(LIMIT_CONNECTIONS_MIN), long(LIMIT_CONNECTIONS_MAX));
|
||||
mConnectionLimit = llclamp(value, long(HTTP_CONNECTION_LIMIT_MIN), long(HTTP_CONNECTION_LIMIT_MAX));
|
||||
break;
|
||||
|
||||
case HttpRequest::CP_PER_HOST_CONNECTION_LIMIT:
|
||||
mPerHostConnectionLimit = llclamp(value, long(LIMIT_CONNECTIONS_MIN), mConnectionLimit);
|
||||
mPerHostConnectionLimit = llclamp(value, long(HTTP_CONNECTION_LIMIT_MIN), mConnectionLimit);
|
||||
break;
|
||||
|
||||
case HttpRequest::CP_ENABLE_PIPELINING:
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ namespace LLCore
|
|||
|
||||
HttpPolicyGlobal::HttpPolicyGlobal()
|
||||
: mSetMask(0UL),
|
||||
mConnectionLimit(DEFAULT_CONNECTIONS),
|
||||
mTrace(TRACE_OFF),
|
||||
mConnectionLimit(HTTP_CONNECTION_LIMIT_DEFAULT),
|
||||
mTrace(HTTP_TRACE_OFF),
|
||||
mUseLLProxy(0)
|
||||
{}
|
||||
|
||||
|
|
@ -66,11 +66,11 @@ HttpStatus HttpPolicyGlobal::set(HttpRequest::EGlobalPolicy opt, long value)
|
|||
switch (opt)
|
||||
{
|
||||
case HttpRequest::GP_CONNECTION_LIMIT:
|
||||
mConnectionLimit = llclamp(value, long(LIMIT_CONNECTIONS_MIN), long(LIMIT_CONNECTIONS_MAX));
|
||||
mConnectionLimit = llclamp(value, long(HTTP_CONNECTION_LIMIT_MIN), long(HTTP_CONNECTION_LIMIT_MAX));
|
||||
break;
|
||||
|
||||
case HttpRequest::GP_TRACE:
|
||||
mTrace = llclamp(value, long(TRACE_MIN), long(TRACE_MAX));
|
||||
mTrace = llclamp(value, long(HTTP_TRACE_MIN), long(HTTP_TRACE_MAX));
|
||||
break;
|
||||
|
||||
case HttpRequest::GP_LLPROXY:
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ namespace LLCore
|
|||
/// important of those rules is that any iterator becomes invalid
|
||||
/// on element erasure. So pay attention.
|
||||
///
|
||||
/// If LLCORE_READY_QUEUE_IGNORES_PRIORITY tests true, the class
|
||||
/// If LLCORE_HTTP_READY_QUEUE_IGNORES_PRIORITY tests true, the class
|
||||
/// implements a std::priority_queue interface but on std::deque
|
||||
/// behavior to eliminate sensitivity to priority. In the future,
|
||||
/// this will likely become the only behavior or it may become
|
||||
|
|
@ -54,7 +54,7 @@ namespace LLCore
|
|||
/// Threading: not thread-safe. Expected to be used entirely by
|
||||
/// a single thread, typically a worker thread of some sort.
|
||||
|
||||
#if LLCORE_READY_QUEUE_IGNORES_PRIORITY
|
||||
#if LLCORE_HTTP_READY_QUEUE_IGNORES_PRIORITY
|
||||
|
||||
typedef std::deque<HttpOpRequest *> HttpReadyQueueBase;
|
||||
|
||||
|
|
@ -64,7 +64,7 @@ typedef std::priority_queue<HttpOpRequest *,
|
|||
std::deque<HttpOpRequest *>,
|
||||
LLCore::HttpOpRequestCompare> HttpReadyQueueBase;
|
||||
|
||||
#endif // LLCORE_READY_QUEUE_IGNORES_PRIORITY
|
||||
#endif // LLCORE_HTTP_READY_QUEUE_IGNORES_PRIORITY
|
||||
|
||||
class HttpReadyQueue : public HttpReadyQueueBase
|
||||
{
|
||||
|
|
@ -82,7 +82,7 @@ protected:
|
|||
|
||||
public:
|
||||
|
||||
#if LLCORE_READY_QUEUE_IGNORES_PRIORITY
|
||||
#if LLCORE_HTTP_READY_QUEUE_IGNORES_PRIORITY
|
||||
// Types and methods needed to make a std::deque look
|
||||
// more like a std::priority_queue, at least for our
|
||||
// purposes.
|
||||
|
|
@ -103,7 +103,7 @@ public:
|
|||
push_back(v);
|
||||
}
|
||||
|
||||
#endif // LLCORE_READY_QUEUE_IGNORES_PRIORITY
|
||||
#endif // LLCORE_HTTP_READY_QUEUE_IGNORES_PRIORITY
|
||||
|
||||
const container_type & get_container() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -55,8 +55,8 @@ HttpService::HttpService()
|
|||
{
|
||||
// Create the default policy class
|
||||
HttpPolicyClass pol_class;
|
||||
pol_class.set(HttpRequest::CP_CONNECTION_LIMIT, DEFAULT_CONNECTIONS);
|
||||
pol_class.set(HttpRequest::CP_PER_HOST_CONNECTION_LIMIT, DEFAULT_CONNECTIONS);
|
||||
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);
|
||||
}
|
||||
|
|
@ -150,7 +150,7 @@ void HttpService::term()
|
|||
HttpRequest::policy_t HttpService::createPolicyClass()
|
||||
{
|
||||
const HttpRequest::policy_t policy_class(mPolicyClasses.size());
|
||||
if (policy_class >= POLICY_CLASS_LIMIT)
|
||||
if (policy_class >= HTTP_POLICY_CLASS_LIMIT)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -219,12 +219,12 @@ bool HttpService::changePriority(HttpHandle handle, HttpRequest::priority_t prio
|
|||
}
|
||||
|
||||
|
||||
/// Try to find the given request handle on any of the request
|
||||
/// queues and cancel the operation.
|
||||
///
|
||||
/// @return True if the request was canceled.
|
||||
///
|
||||
/// Threading: callable by worker thread.
|
||||
/// Try to find the given request handle on any of the request
|
||||
/// queues and cancel the operation.
|
||||
///
|
||||
/// @return True if the request was canceled.
|
||||
///
|
||||
/// Threading: callable by worker thread.
|
||||
bool HttpService::cancel(HttpHandle handle)
|
||||
{
|
||||
bool canceled(false);
|
||||
|
|
@ -297,7 +297,7 @@ void HttpService::threadRun(LLCoreInt::HttpThread * thread)
|
|||
// Determine whether to spin, sleep briefly or sleep for next request
|
||||
if (REQUEST_SLEEP != loop)
|
||||
{
|
||||
ms_sleep(LOOP_SLEEP_NORMAL_MS);
|
||||
ms_sleep(HTTP_SERVICE_LOOP_SLEEP_NORMAL_MS);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -321,11 +321,11 @@ HttpService::ELoopSpeed HttpService::processRequestQueue(ELoopSpeed loop)
|
|||
if (! mExitRequested)
|
||||
{
|
||||
// Setup for subsequent tracing
|
||||
long tracing(TRACE_OFF);
|
||||
long tracing(HTTP_TRACE_OFF);
|
||||
mPolicy->getGlobalOptions().get(HttpRequest::GP_TRACE, &tracing);
|
||||
op->mTracing = (std::max)(op->mTracing, int(tracing));
|
||||
|
||||
if (op->mTracing > TRACE_OFF)
|
||||
if (op->mTracing > HTTP_TRACE_OFF)
|
||||
{
|
||||
LL_INFOS("CoreHttp") << "TRACE, FromRequestQueue, Handle: "
|
||||
<< static_cast<HttpHandle>(op)
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ class HttpPolicy;
|
|||
class HttpLibcurl;
|
||||
|
||||
|
||||
/// The HttpService class does the work behind the request queue. It
|
||||
/// The HttpService class does the work behind the request queue. It
|
||||
/// oversees the HTTP workflow carrying out a number of tasks:
|
||||
/// - Pulling requests from the global request queue
|
||||
/// - Executing 'immediate' requests directly
|
||||
|
|
@ -76,7 +76,7 @@ class HttpLibcurl;
|
|||
/// HttpPolicy and HttpLibcurl (transport). These always exist in a
|
||||
/// 1:1:1 relationship with HttpService managing instances of the other
|
||||
/// two. So, these classes do not use reference counting to refer
|
||||
/// to one-another, their lifecycles are always managed together.
|
||||
/// to one another, their lifecycles are always managed together.
|
||||
|
||||
class HttpService
|
||||
{
|
||||
|
|
@ -206,7 +206,7 @@ protected:
|
|||
|
||||
// === shared data ===
|
||||
static volatile EState sState;
|
||||
HttpRequestQueue * mRequestQueue;
|
||||
HttpRequestQueue * mRequestQueue; // Refcounted
|
||||
LLAtomicU32 mExitRequested;
|
||||
LLCoreInt::HttpThread * mThread;
|
||||
|
||||
|
|
|
|||
|
|
@ -60,8 +60,10 @@
|
|||
/// Using the library is fairly easy. Global setup needs a few
|
||||
/// steps:
|
||||
///
|
||||
/// - libcurl initialization with thread-safely callbacks for c-ares
|
||||
/// DNS lookups.
|
||||
/// - libcurl initialization including thread-safely callbacks for SSL:
|
||||
/// . curl_global_init(...)
|
||||
/// . CRYPTO_set_locking_callback(...)
|
||||
/// . CRYPTO_set_id_callback(...)
|
||||
/// - HttpRequest::createService() called to instantiate singletons
|
||||
/// and support objects.
|
||||
///
|
||||
|
|
@ -90,8 +92,18 @@
|
|||
/// - Do completion processing in your onCompletion() method.
|
||||
///
|
||||
/// Code fragments:
|
||||
/// <TBD>
|
||||
/// Rather than a poorly-maintained example in comments, look in the
|
||||
/// example subdirectory which is a minimal yet functional tool to do
|
||||
/// GET request performance testing. With four calls:
|
||||
///
|
||||
/// init_curl();
|
||||
/// LLCore::HttpRequest::createService();
|
||||
/// LLCore::HttpRequest::startThread();
|
||||
/// LLCore::HttpRequest * hr = new LLCore::HttpRequest();
|
||||
///
|
||||
/// the program is basically ready to issue requests.
|
||||
///
|
||||
|
||||
|
||||
#include "linden_common.h" // Modifies curl/curl.h interfaces
|
||||
|
||||
|
|
|
|||
|
|
@ -36,9 +36,9 @@ namespace LLCore
|
|||
HttpOptions::HttpOptions()
|
||||
: RefCounted(true),
|
||||
mWantHeaders(false),
|
||||
mTracing(TRACE_OFF),
|
||||
mTimeout(DEFAULT_TIMEOUT),
|
||||
mRetries(DEFAULT_RETRY_COUNT)
|
||||
mTracing(HTTP_TRACE_OFF),
|
||||
mTimeout(HTTP_REQUEST_TIMEOUT_DEFAULT),
|
||||
mRetries(HTTP_RETRY_COUNT_DEFAULT)
|
||||
{}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue