summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorRider Linden <none@none>2015-04-10 17:23:58 -0700
committerRider Linden <none@none>2015-04-10 17:23:58 -0700
commitd0c85b6dd964164b6d92103ad65b5cd859197de2 (patch)
tree4d6cfc9fe3db9b42ce1b1fe7acc373ab9cba7ca2 /indra
parent794cdbc2ae2d7078a7af5319e84667f0d6b15297 (diff)
Adding support for DELETE, PATCH and COPY
Diffstat (limited to 'indra')
-rwxr-xr-xindra/llcorehttp/_httpoprequest.cpp68
-rwxr-xr-xindra/llcorehttp/_httpoprequest.h26
-rwxr-xr-xindra/llcorehttp/httprequest.cpp94
-rwxr-xr-xindra/llcorehttp/httprequest.h63
-rw-r--r--indra/llmessage/llcorehttputil.cpp40
-rw-r--r--indra/llmessage/llcorehttputil.h35
6 files changed, 315 insertions, 11 deletions
diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp
index 7c2309b31d..b1b05dc285 100755
--- a/indra/llcorehttp/_httpoprequest.cpp
+++ b/indra/llcorehttp/_httpoprequest.cpp
@@ -357,6 +357,46 @@ HttpStatus HttpOpRequest::setupPut(HttpRequest::policy_t policy_id,
}
+HttpStatus HttpOpRequest::setupDelete(HttpRequest::policy_t policy_id,
+ HttpRequest::priority_t priority,
+ const std::string & url,
+ HttpOptions * options,
+ HttpHeaders * headers)
+{
+ setupCommon(policy_id, priority, url, NULL, options, headers);
+ mReqMethod = HOR_DELETE;
+
+ return HttpStatus();
+}
+
+
+HttpStatus HttpOpRequest::setupPatch(HttpRequest::policy_t policy_id,
+ HttpRequest::priority_t priority,
+ const std::string & url,
+ BufferArray * body,
+ HttpOptions * options,
+ HttpHeaders * headers)
+{
+ setupCommon(policy_id, priority, url, body, options, headers);
+ mReqMethod = HOR_PATCH;
+
+ return HttpStatus();
+}
+
+
+HttpStatus HttpOpRequest::setupCopy(HttpRequest::policy_t policy_id,
+ HttpRequest::priority_t priority,
+ const std::string & url,
+ HttpOptions * options,
+ HttpHeaders * headers)
+{
+ setupCommon(policy_id, priority, url, NULL, options, headers);
+ mReqMethod = HOR_COPY;
+
+ return HttpStatus();
+}
+
+
void HttpOpRequest::setupCommon(HttpRequest::policy_t policy_id,
HttpRequest::priority_t priority,
const std::string & url,
@@ -549,8 +589,6 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
case HOR_GET:
code = curl_easy_setopt(mCurlHandle, CURLOPT_HTTPGET, 1);
check_curl_easy_code(code, CURLOPT_HTTPGET);
- mCurlHeaders = curl_slist_append(mCurlHeaders, "Connection: keep-alive");
- mCurlHeaders = curl_slist_append(mCurlHeaders, "Keep-alive: 300");
break;
case HOR_POST:
@@ -569,12 +607,14 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
code = curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDSIZE, data_size);
check_curl_easy_code(code, CURLOPT_POSTFIELDSIZE);
mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:");
- mCurlHeaders = curl_slist_append(mCurlHeaders, "Connection: keep-alive");
- mCurlHeaders = curl_slist_append(mCurlHeaders, "Keep-alive: 300");
}
break;
- case HOR_PUT:
+ case HOR_PATCH:
+ code = curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "PATCH");
+ check_curl_easy_code(code, CURLOPT_CUSTOMREQUEST);
+ // fall through. The rest is the same as PUT
+ case HOR_PUT:
{
code = curl_easy_setopt(mCurlHandle, CURLOPT_UPLOAD, 1);
check_curl_easy_code(code, CURLOPT_UPLOAD);
@@ -588,12 +628,19 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
code = curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDS, (void *) NULL);
check_curl_easy_code(code, CURLOPT_POSTFIELDS);
mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:");
- // *TODO: Should this be 'Keep-Alive' ?
- mCurlHeaders = curl_slist_append(mCurlHeaders, "Connection: keep-alive");
- mCurlHeaders = curl_slist_append(mCurlHeaders, "Keep-alive: 300");
}
break;
+ case HOR_DELETE:
+ code = curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "DELETE");
+ check_curl_easy_code(code, CURLOPT_CUSTOMREQUEST);
+ break;
+
+ case HOR_COPY:
+ code = curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "COPY");
+ check_curl_easy_code(code, CURLOPT_CUSTOMREQUEST);
+ break;
+
default:
LL_ERRS(LOG_CORE) << "Invalid HTTP method in request: "
<< int(mReqMethod) << ". Can't recover."
@@ -601,6 +648,11 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
break;
}
+
+ // *TODO: Should this be 'Keep-Alive' ?
+ mCurlHeaders = curl_slist_append(mCurlHeaders, "Connection: keep-alive");
+ mCurlHeaders = curl_slist_append(mCurlHeaders, "Keep-alive: 300");
+
// Tracing
if (mTracing >= HTTP_TRACE_CURL_HEADERS)
{
diff --git a/indra/llcorehttp/_httpoprequest.h b/indra/llcorehttp/_httpoprequest.h
index e71d1d1edf..ca40898a81 100755
--- a/indra/llcorehttp/_httpoprequest.h
+++ b/indra/llcorehttp/_httpoprequest.h
@@ -80,7 +80,10 @@ public:
{
HOR_GET,
HOR_POST,
- HOR_PUT
+ HOR_PUT,
+ HOR_DELETE,
+ HOR_PATCH,
+ HOR_COPY
};
virtual void stageFromRequest(HttpService *);
@@ -126,7 +129,26 @@ public:
HttpOptions * options,
HttpHeaders * headers);
- // Internal method used to setup the libcurl options for a request.
+ HttpStatus setupDelete(HttpRequest::policy_t policy_id,
+ HttpRequest::priority_t priority,
+ const std::string & url,
+ HttpOptions * options,
+ HttpHeaders * headers);
+
+ HttpStatus setupPatch(HttpRequest::policy_t policy_id,
+ HttpRequest::priority_t priority,
+ const std::string & url,
+ BufferArray * body,
+ HttpOptions * options,
+ HttpHeaders * headers);
+
+ HttpStatus setupCopy(HttpRequest::policy_t policy_id,
+ HttpRequest::priority_t priority,
+ const std::string & url,
+ 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
diff --git a/indra/llcorehttp/httprequest.cpp b/indra/llcorehttp/httprequest.cpp
index df8502b947..d4c60a6f14 100755
--- a/indra/llcorehttp/httprequest.cpp
+++ b/indra/llcorehttp/httprequest.cpp
@@ -325,6 +325,100 @@ HttpHandle HttpRequest::requestPut(policy_t policy_id,
return handle;
}
+HttpHandle HttpRequest::requestDelete(policy_t policy_id,
+ priority_t priority,
+ const std::string & url,
+ HttpOptions * options,
+ HttpHeaders * headers,
+ HttpHandler * user_handler)
+{
+ HttpStatus status;
+ HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+
+ HttpOpRequest * op = new HttpOpRequest();
+ if (!(status = op->setupDelete(policy_id, priority, url, options, headers)))
+ {
+ op->release();
+ mLastReqStatus = status;
+ return handle;
+ }
+ op->setReplyPath(mReplyQueue, user_handler);
+ if (!(status = mRequestQueue->addOp(op))) // transfers refcount
+ {
+ op->release();
+ mLastReqStatus = status;
+ return handle;
+ }
+
+ mLastReqStatus = status;
+ handle = static_cast<HttpHandle>(op);
+
+ return handle;
+}
+
+HttpHandle HttpRequest::requestPatch(policy_t policy_id,
+ priority_t priority,
+ const std::string & url,
+ BufferArray * body,
+ HttpOptions * options,
+ HttpHeaders * headers,
+ HttpHandler * user_handler)
+{
+ HttpStatus status;
+ HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+
+ HttpOpRequest * op = new HttpOpRequest();
+ if (!(status = op->setupPatch(policy_id, priority, url, body, options, headers)))
+ {
+ op->release();
+ mLastReqStatus = status;
+ return handle;
+ }
+ op->setReplyPath(mReplyQueue, user_handler);
+ if (!(status = mRequestQueue->addOp(op))) // transfers refcount
+ {
+ op->release();
+ mLastReqStatus = status;
+ return handle;
+ }
+
+ mLastReqStatus = status;
+ handle = static_cast<HttpHandle>(op);
+
+ return handle;
+}
+
+HttpHandle HttpRequest::requestCopy(policy_t policy_id,
+ priority_t priority,
+ const std::string & url,
+ HttpOptions * options,
+ HttpHeaders * headers,
+ HttpHandler * user_handler)
+{
+ HttpStatus status;
+ HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+
+ HttpOpRequest * op = new HttpOpRequest();
+ if (!(status = op->setupCopy(policy_id, priority, url, options, headers)))
+ {
+ op->release();
+ mLastReqStatus = status;
+ return handle;
+ }
+ op->setReplyPath(mReplyQueue, user_handler);
+ if (!(status = mRequestQueue->addOp(op))) // transfers refcount
+ {
+ op->release();
+ mLastReqStatus = status;
+ return handle;
+ }
+
+ mLastReqStatus = status;
+ handle = static_cast<HttpHandle>(op);
+
+ return handle;
+}
+
HttpHandle HttpRequest::requestNoOp(HttpHandler * user_handler)
{
diff --git a/indra/llcorehttp/httprequest.h b/indra/llcorehttp/httprequest.h
index 6688f06eb5..e87a8b691a 100755
--- a/indra/llcorehttp/httprequest.h
+++ b/indra/llcorehttp/httprequest.h
@@ -478,7 +478,68 @@ public:
HttpHandler * handler);
- /// Queue a NoOp request.
+ /// Queue a full HTTP PUT. Query arguments and body may
+ /// be provided. Caller is responsible for escaping and
+ /// encoding and communicating the content types.
+ ///
+ /// @param policy_id @see requestGet()
+ /// @param priority "
+ /// @param url "
+ /// @param options @see requestGet()K(optional)
+ /// @param headers "
+ /// @param handler "
+ /// @return "
+ ///
+ HttpHandle requestDelete(policy_t policy_id,
+ priority_t priority,
+ const std::string & url,
+ HttpOptions * options,
+ HttpHeaders * headers,
+ HttpHandler * user_handler);
+
+ /// Queue a full HTTP PUT. Query arguments and body may
+ /// be provided. Caller is responsible for escaping and
+ /// encoding and communicating the content types.
+ ///
+ /// @param policy_id @see requestGet()
+ /// @param priority "
+ /// @param url "
+ /// @param body Byte stream to be sent as the body. No
+ /// further encoding or escaping will be done
+ /// to the content.
+ /// @param options @see requestGet()K(optional)
+ /// @param headers "
+ /// @param handler "
+ /// @return "
+ ///
+ HttpHandle requestPatch(policy_t policy_id,
+ priority_t priority,
+ const std::string & url,
+ BufferArray * body,
+ HttpOptions * options,
+ HttpHeaders * headers,
+ HttpHandler * user_handler);
+
+ /// Queue a full HTTP PUT. Query arguments and body may
+ /// be provided. Caller is responsible for escaping and
+ /// encoding and communicating the content types.
+ ///
+ /// @param policy_id @see requestGet()
+ /// @param priority "
+ /// @param url "
+ /// @param options @see requestGet()K(optional)
+ /// @param headers "
+ /// @param handler "
+ /// @return "
+ ///
+ HttpHandle requestCopy(policy_t policy_id,
+ priority_t priority,
+ const std::string & url,
+ HttpOptions * options,
+ HttpHeaders * headers,
+ HttpHandler * user_handler);
+
+ /// Queue a NoOp request.
/// The request is queued and serviced by the working thread which
/// immediately processes it and returns the request to the reply
/// queue.
diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp
index a32c4cad22..2d6cca214c 100644
--- a/indra/llmessage/llcorehttputil.cpp
+++ b/indra/llmessage/llcorehttputil.cpp
@@ -142,6 +142,46 @@ HttpHandle requestPutWithLLSD(HttpRequest::ptr_t & request,
url, body, options.get(), headers.get(), handler);
}
+HttpHandle requestPatchWithLLSD(HttpRequest * request,
+ HttpRequest::policy_t policy_id,
+ HttpRequest::priority_t priority,
+ const std::string & url,
+ const LLSD & body,
+ HttpOptions * options,
+ HttpHeaders * headers,
+ HttpHandler * handler)
+{
+ HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
+
+ BufferArray * ba = new BufferArray();
+ BufferArrayStream bas(ba);
+ LLSDSerialize::toXML(body, bas);
+
+ handle = request->requestPatch(policy_id,
+ priority,
+ url,
+ ba,
+ options,
+ headers,
+ handler);
+ ba->release();
+ return handle;
+}
+
+HttpHandle requestPatchWithLLSD(HttpRequest::ptr_t & request,
+ HttpRequest::policy_t policy_id,
+ HttpRequest::priority_t priority,
+ const std::string & url,
+ const LLSD & body,
+ HttpOptions::ptr_t & options,
+ HttpHeaders::ptr_t & headers,
+ HttpHandler * handler)
+{
+ return requestPatchWithLLSD(request.get(), policy_id, priority,
+ url, body, options.get(), headers.get(), handler);
+}
+
+
std::string responseToString(LLCore::HttpResponse * response)
{
static const std::string empty("[Empty]");
diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h
index 471710f61b..6fcf03b95c 100644
--- a/indra/llmessage/llcorehttputil.h
+++ b/indra/llmessage/llcorehttputil.h
@@ -155,6 +155,41 @@ LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & request,
LLCore::HttpHeaders::ptr_t & headers,
LLCore::HttpHandler * handler);
+/// Issue a standard HttpRequest::requestPatch() call but using
+/// and LLSD object as the request body. Conventions are the
+/// same as with that method. Caller is expected to provide
+/// an HttpHeaders object with a correct 'Content-Type:' header.
+/// One will not be provided by this call.
+///
+/// @return If request is successfully issued, the
+/// HttpHandle representing the request.
+/// On error, LLCORE_HTTP_HANDLE_INVALID
+/// is returned and caller can fetch detailed
+/// status with the getStatus() method on the
+/// request object. In case of error, no
+/// request is queued and caller may need to
+/// perform additional cleanup such as freeing
+/// a now-useless HttpHandler object.
+///
+LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest * request,
+ LLCore::HttpRequest::policy_t policy_id,
+ LLCore::HttpRequest::priority_t priority,
+ const std::string & url,
+ const LLSD & body,
+ LLCore::HttpOptions * options,
+ LLCore::HttpHeaders * headers,
+ LLCore::HttpHandler * handler);
+
+LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest::ptr_t & request,
+ LLCore::HttpRequest::policy_t policy_id,
+ LLCore::HttpRequest::priority_t priority,
+ const std::string & url,
+ const LLSD & body,
+ LLCore::HttpOptions::ptr_t & options,
+ LLCore::HttpHeaders::ptr_t & headers,
+ LLCore::HttpHandler * handler);
+
+
/// The HttpCoroHandler is a specialization of the LLCore::HttpHandler for
/// interacting with coroutines. When the request is completed the response
/// will be posted onto the supplied Event Pump.