diff options
Diffstat (limited to 'indra/llcorehttp/httpcommon.h')
-rw-r--r-- | indra/llcorehttp/httpcommon.h | 166 |
1 files changed, 133 insertions, 33 deletions
diff --git a/indra/llcorehttp/httpcommon.h b/indra/llcorehttp/httpcommon.h index 9601f94125..b2db01d038 100644 --- a/indra/llcorehttp/httpcommon.h +++ b/indra/llcorehttp/httpcommon.h @@ -188,9 +188,12 @@ /// #include "linden_common.h" // Modifies curl/curl.h interfaces - +#include "boost/intrusive_ptr.hpp" +#include "boost/shared_ptr.hpp" +#include "boost/weak_ptr.hpp" +#include "boost/function.hpp" #include <string> - +#include <curl/curl.h> namespace LLCore { @@ -206,6 +209,7 @@ namespace LLCore /// becomes invalid and may be recycled for other queued requests. typedef void * HttpHandle; + #define LLCORE_HTTP_HANDLE_INVALID (NULL) /// For internal scheduling and metrics, we use a microsecond @@ -286,52 +290,63 @@ enum HttpError /// 5. Construct an HTTP 301 status code to be treated as success: /// HttpStatus(301, HE_SUCCESS); /// +/// 6. Construct a failed status of HTTP Status 499 with a custom error message +/// HttpStatus(499, "Failed LLSD Response"); struct HttpStatus { typedef unsigned short type_enum_t; HttpStatus() - : mType(LLCORE), - mStatus(HE_SUCCESS) - {} + { + mDetails = boost::shared_ptr<Details>(new Details(LLCORE, HE_SUCCESS)); + } HttpStatus(type_enum_t type, short status) - : mType(type), - mStatus(status) - {} + { + mDetails = boost::shared_ptr<Details>(new Details(type, status)); + } HttpStatus(int http_status) - : mType(http_status), - mStatus(http_status >= 200 && http_status <= 299 - ? HE_SUCCESS - : HE_REPLY_ERROR) - { - llassert(http_status >= 100 && http_status <= 999); - } + { + mDetails = boost::shared_ptr<Details>(new Details(http_status, + (http_status >= 200 && http_status <= 299) ? HE_SUCCESS : HE_REPLY_ERROR)); + llassert(http_status >= 100 && http_status <= 999); + } + + HttpStatus(int http_status, const std::string &message) + { + mDetails = boost::shared_ptr<Details>(new Details(http_status, + (http_status >= 200 && http_status <= 299) ? HE_SUCCESS : HE_REPLY_ERROR)); + llassert(http_status >= 100 && http_status <= 999); + mDetails->mMessage = message; + } HttpStatus(const HttpStatus & rhs) - : mType(rhs.mType), - mStatus(rhs.mStatus) - {} + { + mDetails = rhs.mDetails; + } + + ~HttpStatus() + { + } HttpStatus & operator=(const HttpStatus & rhs) - { - // Don't care if lhs & rhs are the same object + { + mDetails = rhs.mDetails; + return *this; + } - mType = rhs.mType; - mStatus = rhs.mStatus; - return *this; - } + HttpStatus & clone(const HttpStatus &rhs) + { + mDetails = boost::shared_ptr<Details>(new Details(*rhs.mDetails)); + return *this; + } static const type_enum_t EXT_CURL_EASY = 0; ///< mStatus is an error from a curl_easy_*() call static const type_enum_t EXT_CURL_MULTI = 1; ///< mStatus is an error from a curl_multi_*() call static const type_enum_t LLCORE = 2; ///< mStatus is an HE_* error code ///< 100-999 directly represent HTTP status codes - - type_enum_t mType; - short mStatus; - /// Test for successful status in the code regardless /// of error source (internal, libcurl). /// @@ -339,7 +354,7 @@ struct HttpStatus /// operator bool() const { - return 0 == mStatus; + return 0 == mDetails->mStatus; } /// Inverse of previous operator. @@ -347,14 +362,14 @@ struct HttpStatus /// @return 'true' on any error condition bool operator !() const { - return 0 != mStatus; + return 0 != mDetails->mStatus; } /// Equality and inequality tests to bypass bool conversion /// which will do the wrong thing in conditional expressions. bool operator==(const HttpStatus & rhs) const { - return mType == rhs.mType && mStatus == rhs.mStatus; + return (*mDetails == *rhs.mDetails); } bool operator!=(const HttpStatus & rhs) const @@ -395,7 +410,7 @@ struct HttpStatus /// HTTP response status (100 - 999). bool isHttpStatus() const { - return mType >= type_enum_t(100) && mType <= type_enum_t(999); + return mDetails->mType >= type_enum_t(100) && mDetails->mType <= type_enum_t(999); } /// Returns true if the status is one that will be retried @@ -403,9 +418,94 @@ struct HttpStatus /// where that logic needs to be replicated. Only applies /// to failed statuses, successful statuses will return false. bool isRetryable() const; - + + /// Returns the currently set status code as a raw number + /// + short getStatus() const + { + return mDetails->mStatus; + } + + /// Returns the currently set status type + /// + type_enum_t getType() const + { + return mDetails->mType; + } + + /// Returns an optional error message if one has been set. + /// + std::string getMessage() const + { + return mDetails->mMessage; + } + + /// Sets an optional error message + /// + void setMessage(const std::string &message) + { + mDetails->mMessage = message; + } + + /// Retrieves an optionally recorded SSL certificate. + void * getErrorData() const + { + return mDetails->mErrorData; + } + + /// Optionally sets an SSL certificate on this status. + void setErrorData(void *data) + { + mDetails->mErrorData = data; + } + +private: + + struct Details + { + Details(type_enum_t type, short status): + mType(type), + mStatus(status), + mMessage(), + mErrorData(NULL) + {} + + Details(const Details &rhs) : + mType(rhs.mType), + mStatus(rhs.mStatus), + mMessage(rhs.mMessage), + mErrorData(rhs.mErrorData) + {} + + bool operator == (const Details &rhs) const + { + return (mType == rhs.mType) && (mStatus == rhs.mStatus); + } + + type_enum_t mType; + short mStatus; + std::string mMessage; + void * mErrorData; + }; + + boost::shared_ptr<Details> mDetails; + }; // end struct HttpStatus +/// A namespace for several free methods and low level utilities. +namespace LLHttp +{ + typedef boost::shared_ptr<CURL> CURL_ptr; + + void initialize(); + void cleanup(); + + CURL_ptr createEasyHandle(); + std::string getCURLVersion(); + + void check_curl_code(CURLcode code, int curl_setopt_option); +} + } // end namespace LLCore #endif // _LLCORE_HTTP_COMMON_H_ |