Files
SingularityViewer/indra/llmessage/llhttpclient.h
2014-07-26 02:46:11 +02:00

577 lines
27 KiB
C++

/**
* @file llhttpclient.h
* @brief Declaration of classes for making HTTP client requests.
*
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, 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
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLHTTPCLIENT_H
#define LL_LLHTTPCLIENT_H
/**
* These classes represent the HTTP client framework.
*/
#include <string>
#include <curl/curl.h> // CURLcode
#include <boost/intrusive_ptr.hpp>
#include "llassettype.h"
#include "llhttpstatuscodes.h"
#include "aihttpheaders.h"
#include "aicurlperservice.h"
class LLUUID;
class LLPumpIO;
class LLSD;
class AIHTTPTimeoutPolicy;
class LLBufferArray;
class LLChannelDescriptors;
class AIStateMachine;
class Injector;
class AIEngine;
extern AIHTTPTimeoutPolicy responderIgnore_timeout;
typedef struct _xmlrpc_request* XMLRPC_REQUEST;
typedef struct _xmlrpc_value* XMLRPC_VALUE;
extern AIEngine gMainThreadEngine;
// In Viewer 3 this definition is in indra/newview/lltexturefetch.cpp,
// but we need it in two .cpp files, so it's moved here.
//
// BUG-3323/SH-4375
// *NOTE: This is a heuristic value. Texture fetches have a habit of using a
// value of 32MB to indicate 'get the rest of the image'. Certain ISPs and
// network equipment get confused when they see this in a Range: header. So,
// if the request end is beyond this value, we issue an open-ended Range:
// request (e.g. 'Range: <start>-') which seems to fix the problem.
static const S32 HTTP_REQUESTS_RANGE_END_MAX = 20000000;
// Output parameter of AICurlPrivate::CurlEasyRequest::getResult.
// Used in XMLRPCResponder.
struct AITransferInfo {
AITransferInfo() : mSizeDownload(0.0), mTotalTime(0.0), mSpeedDownload(0.0) { }
F64 mSizeDownload;
F64 mTotalTime;
F64 mSpeedDownload;
};
// Events generated by AICurlPrivate::BufferedCurlEasyRequest
struct AIBufferedCurlEasyRequestEvents {
virtual void received_HTTP_header(void) = 0; // For example "HTTP/1.0 200 OK", the first header of a reply.
virtual void received_header(std::string const& key, std::string const& value) = 0; // Subsequent headers.
virtual void completed_headers(U32 status, std::string const& reason, AITransferInfo* info) = 0; // Transaction completed.
};
enum EKeepAlive {
no_keep_alive = 0,
keep_alive
};
enum EDoesAuthentication {
no_does_authentication = 0,
does_authentication
};
enum EAllowCompressedReply {
no_allow_compressed_reply = 0,
allow_compressed_reply
};
#ifdef DEBUG_CURLIO
enum EDebugCurl {
debug_off = 0,
debug_on
};
#define DEBUG_CURLIO_PARAM(p) ,p
#else
#define DEBUG_CURLIO_PARAM(p)
#endif
class LLHTTPClient {
public:
/**
* @brief This enumeration is for specifying the type of request.
*/
enum ERequestAction
{
INVALID,
HTTP_HEAD,
HTTP_GET,
HTTP_PUT,
HTTP_POST,
HTTP_DELETE,
HTTP_MOVE, // Caller will need to set 'Destination' header
REQUEST_ACTION_COUNT
};
/** @name Responder base classes */
//@{
/**
* @class ResponderBase
* @brief Base class for all Responders.
*
* The life cycle of classes derived from this class is as follows:
* They are allocated with new on the line where get(), getByteRange() or post() is called,
* and the pointer to the allocated object is then put in a reference counting ResponderPtr.
* This ResponderPtr is passed to BufferedCurlEasyRequest::prepRequest which stores it in its
* member mResponder. Hence, the life time of a Responder is never longer than its
* associated BufferedCurlEasyRequest, however, if everything works correctly, then normally a
* responder is deleted in BufferedCurlEasyRequest::processOutput by setting
* mReponder to NULL.
*/
class ResponderBase : public AIBufferedCurlEasyRequestEvents {
public:
typedef boost::shared_ptr<LLBufferArray> buffer_ptr_t;
/**
* @brief return true if the status code indicates success.
*/
static bool isGoodStatus(S32 status)
{
return((200 <= status) && (status < 300));
}
protected:
ResponderBase(void);
virtual ~ResponderBase();
// Read body from buffer and put it into mContent. If mStatus indicates success, interpret it as LLSD, otherwise copy it as-is.
void decode_llsd_body(LLChannelDescriptors const& channels, buffer_ptr_t const& buffer);
// Read body from buffer and put it into content. Always copy it as-is.
void decode_raw_body(LLChannelDescriptors const& channels, buffer_ptr_t const& buffer, std::string& content);
protected:
// Associated URL, used for debug output.
std::string mURL;
// Headers received from the server.
AIHTTPReceivedHeaders mReceivedHeaders;
// The curl result code.
CURLcode mCode;
// HTTP status code, if any.
S32 mStatus;
// Reason for error if mStatus is not good.
std::string mReason;
// Content interpreted as LLSD.
LLSD mContent;
// Set when the transaction finished (with or without errors).
bool mFinished;
public:
// Called to set the URL of the current request for this Responder,
// used only when printing debug output regarding activity of the Responder.
void setURL(std::string const& url);
// Accessors.
std::string const& getURL(void) const { return mURL; }
CURLcode result_code(void) const { return mCode; }
protected:
// Short cut.
void setResult(S32 status, std::string const& reason, LLSD const& content) { mStatus = status; mReason = reason; mContent = content; mFinished = true; }
// Call these only from the httpSuccess/httpFailure/httpComplete methods of derived classes.
LLSD const& getContent(void) const { return mContent; }
// You can just access mReceivedHeaders directly from derived classes, but added this accessor
// for convenience because upstream introduced this method as part of a new API.
AIHTTPReceivedHeaders const& getResponseHeaders(void) const
{
// If this fails then you need to add '/*virtual*/ bool needsHeaders(void) const { return true; }' to the most derived class.
llassert(needsHeaders());
return mReceivedHeaders;
}
// Another convenience method to match upstream.
std::string dumpResponse(void) const;
public:
// The next two are public because blocking_request() needs access too.
S32 getStatus(void) const { return mStatus; }
std::string const& getReason(void) const { return mReason; }
public:
// Called by BufferedCurlEasyRequest::timed_out or BufferedCurlEasyRequest::processOutput.
virtual void finished(CURLcode code, U32 http_status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) = 0;
// Return true if the curl thread is done with this transaction.
// If this returns true then it is guaranteed that none of the
// virtual functions will be called anymore: the curl thread
// will not access this object anymore.
// Note that normally you don't need to call this function.
bool is_finished(void) const { return mFinished; }
protected:
// AIBufferedCurlEasyRequestEvents
// These three events are only actually called for classes that implement a needsHeaders() that returns true.
// Called when the "HTTP/1.x <status> <reason>" header is received.
/*virtual*/ void received_HTTP_header(void)
{
// It's possible that this page was moved (302), so we already saw headers
// from the 302 page and are starting over on the new page now.
// Erase all headers EXCEPT the cookies.
AIHTTPReceivedHeaders set_cookie_headers;
AIHTTPReceivedHeaders::range_type cookies;
if (mReceivedHeaders.getValues("set-cookie", cookies))
{
for (AIHTTPReceivedHeaders::iterator_type cookie = cookies.first; cookie != cookies.second; ++cookie)
{
set_cookie_headers.addHeader(cookie->first, cookie->second);
}
}
// Replace headers with just the cookie headers.
mReceivedHeaders.swap(set_cookie_headers);
}
// Called for all remaining headers.
/*virtual*/ void received_header(std::string const& key, std::string const& value)
{
mReceivedHeaders.addHeader(key, value);
}
// Called when the whole transaction is completed (also the body was received), but before the body is processed.
/*virtual*/ void completed_headers(U32 status, std::string const& reason, AITransferInfo* info)
{
mStatus = status;
mReason = reason;
completedHeaders();
}
// Extract cookie 'key' from mReceivedHeaders and return the string 'key=value', or an empty string if key does not exists.
std::string const& get_cookie(std::string const& key);
public:
// Derived classes that implement completed_headers()/completedHeaders() should return true here.
virtual bool needsHeaders(void) const { return false; }
// A derived class should return true if curl should close the connection when done.
// The default is to keep connections open for possible reuse.
virtual bool forbidReuse(void) const { return false; }
// A derived class should return true if curl should not follow redirections, but instead pass redirection status codes to the responder.
// The default is to follow redirections and not pass them to the responder.
virtual bool pass_redirect_status(void) const { return false; }
// If this function returns false then we generate an error when a redirect status (300..399) is received.
virtual bool redirect_status_ok(void) const { return true; }
// Overridden by LLEventPollResponder to return true.
virtual bool is_event_poll(void) const { return false; }
// Returns the capability type used by this responder.
virtual AICapabilityType capability_type(void) const { return cap_other; }
// Timeout policy to use.
virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const;
// The name of the derived responder object. For debugging purposes.
virtual char const* getName(void) const = 0;
protected:
// Derived classes can override this to get the HTML headers that were received, when the message is completed.
// Only actually called for classes that implement a needsHeaders() that returns true.
virtual void completedHeaders(void)
{
// The default does nothing.
}
private:
// Used by ResponderPtr. Object is deleted when reference count reaches zero.
LLAtomicU32 mReferenceCount;
friend void intrusive_ptr_add_ref(ResponderBase* p); // Called by boost::intrusive_ptr when a new copy of a boost::intrusive_ptr<ResponderBase> is made.
friend void intrusive_ptr_release(ResponderBase* p); // Called by boost::intrusive_ptr when a boost::intrusive_ptr<ResponderBase> is destroyed.
// This function must delete the ResponderBase object when the reference count reaches zero.
};
// Responders derived from this base class should use HTTPClient::head or HTTPClient::getHeaderOnly.
// That will set the curl option CURLOPT_NOBODY so that only headers are received.
class ResponderHeadersOnly : public ResponderBase {
private:
/*virtual*/ bool needsHeaders(void) const { return true; }
protected:
// ResponderBase event
// The responder finished. Do not override this function in derived classes; override completedRaw instead.
/*virtual*/ void finished(CURLcode code, U32 http_status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer)
{
mCode = code;
mStatus = http_status;
mReason = reason;
// Allow classes derived from ResponderHeadersOnly to override completedHeaders.
completedHeaders();
mFinished = true;
}
protected:
#ifdef SHOW_ASSERT
// Responders derived from this class must override completedHeaders.
// They may not attempt to override any of the virual functions defined by ResponderBase.
// Define those functions here with different parameters in order to cause a compile
// warning when a class accidently tries to override them.
enum YOU_MAY_ONLY_OVERRIDE_COMPLETED_HEADERS { };
virtual void completedRaw(YOU_MAY_ONLY_OVERRIDE_COMPLETED_HEADERS) { }
virtual void httpCompleted(YOU_MAY_ONLY_OVERRIDE_COMPLETED_HEADERS) { }
virtual void httpSuccess(YOU_MAY_ONLY_OVERRIDE_COMPLETED_HEADERS) { }
virtual void httpFailure(YOU_MAY_ONLY_OVERRIDE_COMPLETED_HEADERS) { }
#endif
};
/**
* @class ResponderWithCompleted
* @brief Base class for Responders that implement completed, or completedRaw if the response is not LLSD.
*/
class ResponderWithCompleted : public ResponderBase {
protected:
// ResponderBase event
// The responder finished. Do not override this function in derived classes; override completedRaw instead.
/*virtual*/ void finished(CURLcode code, U32 http_status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer)
{
mCode = code;
mStatus = http_status;
mReason = reason;
// Allow classes derived from ResponderWithCompleted to override completedRaw
// (if not they should override completed or be derived from ResponderWithResult instead).
completedRaw(channels, buffer);
mFinished = true;
}
protected:
// Events generated by this class.
// Derived classes can override this to get the raw data of the body of the HTML message that was received.
// The default is to interpret the content as LLSD and call httpCompleted().
virtual void completedRaw(LLChannelDescriptors const& channels, buffer_ptr_t const& buffer);
// ... or, derived classes can override this to get LLSD content when the message is completed.
// The default aborts, as it should never be called (can't make it pure virtual though, so
// classes that override completedRaw don't need to implement this function, too).
virtual void httpCompleted(void);
public:
// Ugly LL API...
void completeResult(S32 status, std::string const& reason, LLSD const& content) { mCode = CURLE_OK; setResult(status, reason, content); httpCompleted(); }
#ifdef SHOW_ASSERT
// Responders derived from this class must override either completedRaw or completed.
// They may not attempt to override any of the virual functions defined by ResponderBase.
// Define those functions here with different parameters in order to cause a compile
// warning when a class accidently tries to override them.
enum YOU_ARE_DERIVING_FROM_THE_WRONG_CLASS { };
virtual void httpSuccess(YOU_ARE_DERIVING_FROM_THE_WRONG_CLASS) { }
virtual void httpFailure(YOU_ARE_DERIVING_FROM_THE_WRONG_CLASS) { }
#endif
};
/**
* @class ResponderWithResult
* @brief Base class for reponders that expect LLSD in the body of the reply.
*
* Classes derived from ResponderWithResult must implement result, and either errorWithContent or error.
*/
class ResponderWithResult : public ResponderBase {
protected:
// The responder finished. Do not override this function in derived classes; use ResponderWithCompleted instead.
/*virtual*/ void finished(CURLcode code, U32 http_status, std::string const& reason, LLChannelDescriptors const& channels, buffer_ptr_t const& buffer);
protected:
// Events generated by this class.
// Derived classes must override this to receive the content of a body upon success.
virtual void httpSuccess(void) = 0;
// ... or, derived classes can override this to get informed when a bad HTML status code is received.
// The default prints the error to llinfos.
virtual void httpFailure(void);
public:
// Called from LLSDMessage::ResponderAdapter::listener.
// LLSDMessage::ResponderAdapter is a hack, showing among others by fact that it needs these functions.
void failureResult(U32 status, std::string const& reason, LLSD const& content, CURLcode code = CURLE_OK) { mCode = code; setResult(status, reason, content); httpFailure(); }
void successResult(LLSD const& content) { mCode = CURLE_OK; setResult(HTTP_OK, "", content); httpSuccess(); }
#ifdef SHOW_ASSERT
// Responders derived from this class must override result, and either errorWithContent or error.
// They may not attempt to override any of the virual functions defined by ResponderWithCompleted.
// Define those functions here with different parameter in order to cause a compile
// warning when a class accidently tries to override them.
enum YOU_ARE_DERIVING_FROM_THE_WRONG_CLASS { };
virtual void completedRaw(YOU_ARE_DERIVING_FROM_THE_WRONG_CLASS) { }
virtual void httpCompleted(YOU_ARE_DERIVING_FROM_THE_WRONG_CLASS) { }
#endif
};
/**
* @class ResponderIgnoreBody
* @brief Base class for responders that ignore the result body.
*/
class ResponderIgnoreBody : public ResponderWithResult {
void httpSuccess(void) { }
};
/**
* @class ResponderIgnore
* @brief Responder that ignores the reply, if any, from the server.
*/
class ResponderIgnore : public ResponderIgnoreBody {
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return responderIgnore_timeout;}
/*virtual*/ char const* getName(void) const { return "ResponderIgnore"; }
};
// A Responder is passed around as ResponderPtr, which causes it to automatically
// destruct when there are no pointers left pointing to it.
typedef boost::intrusive_ptr<ResponderBase> ResponderPtr;
//@}
/** General API to request a transfer. */
static void request(
std::string const& url,
ERequestAction method,
Injector* body_injector,
ResponderPtr responder,
AIHTTPHeaders& headers,
AIPerService::Approvement* approved/*,*/
DEBUG_CURLIO_PARAM(EDebugCurl debug),
EKeepAlive keepalive = keep_alive,
EDoesAuthentication does_auth = no_does_authentication,
EAllowCompressedReply allow_compression = allow_compressed_reply,
AIStateMachine* parent = NULL,
/*AIStateMachine::state_type*/ U32 new_parent_state = 0,
AIEngine* default_engine = &gMainThreadEngine);
/** @name non-blocking API */
//@{
static void head(std::string const& url, ResponderHeadersOnly* responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off));
static void head(std::string const& url, ResponderHeadersOnly* responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off))
{ AIHTTPHeaders headers; head(url, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); }
static bool getByteRange(std::string const& url, AIHTTPHeaders& headers, S32 offset, S32 bytes, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off));
static bool getByteRange(std::string const& url, S32 offset, S32 bytes, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off))
{ AIHTTPHeaders headers; return getByteRange(url, headers, offset, bytes, responder/*,*/ DEBUG_CURLIO_PARAM(debug)); }
static void get(std::string const& url, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off));
static void get(std::string const& url, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off))
{ AIHTTPHeaders headers; get(url, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); }
static void get(std::string const& url, LLSD const& query, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off));
static void get(std::string const& url, LLSD const& query, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off))
{ AIHTTPHeaders headers; get(url, query, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); }
static void put(std::string const& url, LLSD const& body, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off));
static void put(std::string const& url, LLSD const& body, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off))
{ AIHTTPHeaders headers; put(url, body, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); }
static void getHeaderOnly(std::string const& url, ResponderHeadersOnly* responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off));
static void getHeaderOnly(std::string const& url, ResponderHeadersOnly* responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off))
{ AIHTTPHeaders headers; getHeaderOnly(url, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); }
static void post(std::string const& url, LLSD const& body, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive, AIStateMachine* parent = NULL, U32 new_parent_state = 0);
static void post(std::string const& url, LLSD const& body, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive, AIStateMachine* parent = NULL, U32 new_parent_state = 0)
{ AIHTTPHeaders headers; post(url, body, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive, parent, new_parent_state); }
static void post_approved(std::string const& url, LLSD const& body, ResponderPtr responder, AIHTTPHeaders& headers, AIPerService::Approvement* approved/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive, AIStateMachine* parent = NULL, U32 new_parent_state = 0);
static void post_approved(std::string const& url, LLSD const& body, ResponderPtr responder, AIPerService::Approvement* approved/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive, AIStateMachine* parent = NULL, U32 new_parent_state = 0)
{ AIHTTPHeaders headers; post_approved(url, body, responder, headers, approved/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive, parent, new_parent_state); }
/** Takes ownership of request and deletes it when sent */
static void postXMLRPC(std::string const& url, XMLRPC_REQUEST request, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive);
static void postXMLRPC(std::string const& url, XMLRPC_REQUEST request, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive)
{ AIHTTPHeaders headers; postXMLRPC(url, request, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive); }
static void postXMLRPC(std::string const& url, char const* method, XMLRPC_VALUE value, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive);
static void postXMLRPC(std::string const& url, char const* method, XMLRPC_VALUE value, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive)
{ AIHTTPHeaders headers; postXMLRPC(url, method, value, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive); }
/** Takes ownership of data and deletes it when sent */
static void postRaw(std::string const& url, const char* data, S32 size, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive);
static void postRaw(std::string const& url, const char* data, S32 size, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive)
{ AIHTTPHeaders headers; postRaw(url, data, size, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive); }
static void postFile(std::string const& url, std::string const& filename, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive);
static void postFile(std::string const& url, std::string const& filename, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive)
{ AIHTTPHeaders headers; postFile(url, filename, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive); }
static void postFile(std::string const& url, const LLUUID& uuid, LLAssetType::EType asset_type, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive);
static void postFile(std::string const& url, const LLUUID& uuid, LLAssetType::EType asset_type, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off), EKeepAlive keepalive = keep_alive)
{ AIHTTPHeaders headers; postFile(url, uuid, asset_type, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug), keepalive); }
static void del(std::string const& url, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off));
static void del(std::string const& url, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off))
{ AIHTTPHeaders headers; del(url, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); }
///< sends a DELETE method, but we can't call it delete in c++
/**
* @brief Send a MOVE webdav method
*
* @param url The complete serialized (and escaped) url to get.
* @param destination The complete serialized destination url.
* @param responder The responder that will handle the result.
* @param headers A map of key:value headers to pass to the request
* @param timeout The number of seconds to give the server to respond.
*/
static void move(std::string const& url, std::string const& destination, ResponderPtr responder, AIHTTPHeaders& headers/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off));
static void move(std::string const& url, std::string const& destination, ResponderPtr responder/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off))
{ AIHTTPHeaders headers; move(url, destination, responder, headers/*,*/ DEBUG_CURLIO_PARAM(debug)); }
//@}
/**
* @brief Blocking HTTP GET that returns an LLSD map of status and body.
*
* @param url the complete serialized (and escaped) url to get
* @return An LLSD of { 'status':status, 'body':payload }
*/
static LLSD blockingGet(std::string const& url/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off));
/**
* @brief Blocking HTTP GET that returns the raw body.
*
* @param url the complete serialized (and escaped) url to get
* @param result the target string to write the body to
* @return HTTP status
*/
static U32 blockingGetRaw(const std::string& url, std::string& result/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off));
/**
* @brief Blocking HTTP POST that returns an LLSD map of status and body.
*
* @param url the complete serialized (and escaped) url to get
* @param body the LLSD post body
* @return An LLSD of { 'status':status (an int), 'body':payload (an LLSD) }
*/
static LLSD blockingPost(std::string const& url, LLSD const& body/*,*/ DEBUG_CURLIO_PARAM(EDebugCurl debug = debug_off));
};
#endif // LL_LLHTTPCLIENT_H