summaryrefslogtreecommitdiff
path: root/indra/llcorehttp/_httpoprequest.cpp
diff options
context:
space:
mode:
authorMonty Brandenberg <monty@lindenlab.com>2012-06-01 14:07:34 -0400
committerMonty Brandenberg <monty@lindenlab.com>2012-06-01 14:07:34 -0400
commitb8edacd0bb4feacc3ac1d61421e600c75ab87f7c (patch)
tree8f0e359445e324e4694e79526e443d5e6c90fab4 /indra/llcorehttp/_httpoprequest.cpp
parent8fc350125c671baeae6b7f8b1814251009f4f50a (diff)
Major steps towards implementing the policy component.
Identified and reacted to the priority inversion problem we have in texturefetch. Includes the introduction of a priority_queue for the requests that are ready. Start some parameterization in anticipation of having policy_class everywhere. Removed _assert.h which isn't really needed in indra codebase. Implemented async setPriority request (which I hope I can get rid of eventually along with all priorities in this library). Converted to using unsigned int for priority rather than float. Implemented POST and did groundwork for PUT.
Diffstat (limited to 'indra/llcorehttp/_httpoprequest.cpp')
-rw-r--r--indra/llcorehttp/_httpoprequest.cpp113
1 files changed, 111 insertions, 2 deletions
diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp
index 521bd5b879..54b9990057 100644
--- a/indra/llcorehttp/_httpoprequest.cpp
+++ b/indra/llcorehttp/_httpoprequest.cpp
@@ -93,6 +93,7 @@ HttpOpRequest::HttpOpRequest()
mCurlHandle(NULL),
mCurlService(NULL),
mCurlHeaders(NULL),
+ mCurlBodyPos(0),
mReplyBody(NULL),
mReplyOffset(0),
mReplyLength(0),
@@ -267,12 +268,46 @@ HttpStatus HttpOpRequest::setupGetByteRange(unsigned int policy_id,
}
-HttpStatus HttpOpRequest::prepareForGet(HttpService * service)
+HttpStatus HttpOpRequest::setupPost(unsigned int policy_id,
+ float priority,
+ const std::string & url,
+ BufferArray * body,
+ HttpOptions * options,
+ HttpHeaders * headers)
+{
+ HttpStatus status;
+
+ mProcFlags = 0;
+ mReqPolicy = policy_id;
+ mReqPriority = priority;
+ mReqMethod = HOR_POST;
+ mReqURL = url;
+ if (body)
+ {
+ body->addRef();
+ mReqBody = body;
+ }
+ if (headers && ! mReqHeaders)
+ {
+ headers->addRef();
+ mReqHeaders = headers;
+ }
+ if (options && ! mReqOptions)
+ {
+ mReqOptions = new HttpOptions(*options);
+ }
+
+ return status;
+}
+
+
+HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
{
// *FIXME: better error handling later
HttpStatus status;
mCurlHandle = curl_easy_init();
+ // curl_easy_setopt(mCurlHandle, CURLOPT_VERBOSE, 1);
curl_easy_setopt(mCurlHandle, CURLOPT_TIMEOUT, 30);
curl_easy_setopt(mCurlHandle, CURLOPT_CONNECTTIMEOUT, 30);
curl_easy_setopt(mCurlHandle, CURLOPT_NOSIGNAL, 1);
@@ -280,20 +315,68 @@ HttpStatus HttpOpRequest::prepareForGet(HttpService * service)
curl_easy_setopt(mCurlHandle, CURLOPT_URL, mReqURL.c_str());
curl_easy_setopt(mCurlHandle, CURLOPT_PRIVATE, this);
curl_easy_setopt(mCurlHandle, CURLOPT_ENCODING, "");
+ // *FIXME: Need to deal with proxy setup...
// curl_easy_setopt(handle, CURLOPT_PROXY, "");
+ // *FIXME: Revisit this old DNS timeout setting - may no longer be valid
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_WRITEFUNCTION, writeCallback);
curl_easy_setopt(mCurlHandle, CURLOPT_WRITEDATA, mCurlHandle);
+ curl_easy_setopt(mCurlHandle, CURLOPT_READFUNCTION, readCallback);
+ curl_easy_setopt(mCurlHandle, CURLOPT_READDATA, mCurlHandle);
+ switch (mReqMethod)
+ {
+ case HOR_GET:
+ curl_easy_setopt(mCurlHandle, CURLOPT_HTTPGET, 1);
+ break;
+
+ case HOR_POST:
+ {
+ curl_easy_setopt(mCurlHandle, CURLOPT_POST, 1);
+ long data_size(0);
+ if (mReqBody)
+ {
+ mReqBody->seek(0);
+ data_size = mReqBody->size();
+ }
+ curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDS, static_cast<void *>(NULL));
+ curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDSIZE, data_size);
+ mCurlHeaders = curl_slist_append(mCurlHeaders, "Transfer-Encoding: chunked");
+ mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:");
+ }
+ break;
+
+ case HOR_PUT:
+ {
+ curl_easy_setopt(mCurlHandle, CURLOPT_UPLOAD, 1);
+ long data_size(0);
+ if (mReqBody)
+ {
+ mReqBody->seek(0);
+ data_size = mReqBody->size();
+ }
+ curl_easy_setopt(mCurlHandle, CURLOPT_INFILESIZE, data_size);
+ mCurlHeaders = curl_slist_append(mCurlHeaders, "Transfer-Encoding: chunked");
+ mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:");
+ }
+ break;
+
+ default:
+ // *FIXME: fail out here
+ break;
+ }
+
if (mReqHeaders)
{
mCurlHeaders = append_headers_to_slist(mReqHeaders, mCurlHeaders);
}
mCurlHeaders = curl_slist_append(mCurlHeaders, "Pragma:");
- if (mReqOffset || mReqLength)
+ if ((mReqOffset || mReqLength) && HOR_GET == mReqMethod)
{
static const char * fmt1("Range: bytes=%d-%d");
static const char * fmt2("Range: bytes=%d-");
@@ -347,6 +430,32 @@ size_t HttpOpRequest::writeCallback(void * data, size_t size, size_t nmemb, void
}
+size_t HttpOpRequest::readCallback(void * data, size_t size, size_t nmemb, void * userdata)
+{
+ CURL * handle(static_cast<CURL *>(userdata));
+ HttpOpRequest * op(NULL);
+ curl_easy_getinfo(handle, CURLINFO_PRIVATE, &op);
+ // *FIXME: check the pointer
+
+ if (! op->mReqBody)
+ {
+ return 0;
+ }
+ const size_t req_size(size * nmemb);
+ const size_t body_size(op->mReqBody->size());
+ if (body_size <= op->mCurlBodyPos)
+ {
+ // *FIXME: should probably log this event - unexplained
+ return 0;
+ }
+
+ const size_t do_size((std::min)(req_size, body_size - op->mCurlBodyPos));
+ op->mReqBody->read(static_cast<char *>(data), do_size);
+ op->mCurlBodyPos += do_size;
+ return do_size;
+}
+
+
size_t HttpOpRequest::headerCallback(void * data, size_t size, size_t nmemb, void * userdata)
{
static const char status_line[] = "HTTP/";