Replace CURLOPT_POSTFIELDSIZE_LARGE with CURLOPT_POSTFIELDSIZE
Also adds a more robust interface for setopt that does type checking based on the options used. This fixes one bug where a F32 was passed and interpreted as long. In many cases a U32 or S32 was passed as long, which would fail (only) on a 64bit non-windows big endian machine.
This commit is contained in:
@@ -717,8 +717,78 @@ void intrusive_ptr_release(ThreadSafeCurlEasyRequest* threadsafe_curl_easy_reque
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CURLcode CurlEasyHandle::setopt(CURLoption option, long parameter)
|
||||||
|
{
|
||||||
|
llassert((CURLOPTTYPE_LONG <= option && option < CURLOPTTYPE_LONG + 1000) ||
|
||||||
|
(sizeof(curl_off_t) == sizeof(long) &&
|
||||||
|
CURLOPTTYPE_OFF_T <= option && option < CURLOPTTYPE_OFF_T + 1000));
|
||||||
|
llassert(!mActiveMultiHandle);
|
||||||
|
setErrorBuffer();
|
||||||
|
return check_easy_code(curl_easy_setopt(mEasyHandle, option, parameter));
|
||||||
|
}
|
||||||
|
|
||||||
|
// The standard requires that sizeof(long) < sizeof(long long), so it's safe to overload like this.
|
||||||
|
// We assume that one of them is 64 bit, the size of curl_off_t.
|
||||||
|
CURLcode CurlEasyHandle::setopt(CURLoption option, long long parameter)
|
||||||
|
{
|
||||||
|
llassert(sizeof(curl_off_t) == sizeof(long long) &&
|
||||||
|
CURLOPTTYPE_OFF_T <= option && option < CURLOPTTYPE_OFF_T + 1000);
|
||||||
|
llassert(!mActiveMultiHandle);
|
||||||
|
setErrorBuffer();
|
||||||
|
return check_easy_code(curl_easy_setopt(mEasyHandle, option, parameter));
|
||||||
|
}
|
||||||
|
|
||||||
|
CURLcode CurlEasyHandle::setopt(CURLoption option, void const* parameter)
|
||||||
|
{
|
||||||
|
llassert(CURLOPTTYPE_OBJECTPOINT <= option && option < CURLOPTTYPE_OBJECTPOINT + 1000);
|
||||||
|
setErrorBuffer();
|
||||||
|
return check_easy_code(curl_easy_setopt(mEasyHandle, option, parameter));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEFINE_FUNCTION_SETOPT1(function_type, opt1) \
|
||||||
|
CURLcode CurlEasyHandle::setopt(CURLoption option, function_type parameter) \
|
||||||
|
{ \
|
||||||
|
llassert(option == opt1); \
|
||||||
|
setErrorBuffer(); \
|
||||||
|
return check_easy_code(curl_easy_setopt(mEasyHandle, option, parameter)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEFINE_FUNCTION_SETOPT3(function_type, opt1, opt2, opt3) \
|
||||||
|
CURLcode CurlEasyHandle::setopt(CURLoption option, function_type parameter) \
|
||||||
|
{ \
|
||||||
|
llassert(option == opt1 || option == opt2 || option == opt3); \
|
||||||
|
setErrorBuffer(); \
|
||||||
|
return check_easy_code(curl_easy_setopt(mEasyHandle, option, parameter)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEFINE_FUNCTION_SETOPT4(function_type, opt1, opt2, opt3, opt4) \
|
||||||
|
CURLcode CurlEasyHandle::setopt(CURLoption option, function_type parameter) \
|
||||||
|
{ \
|
||||||
|
llassert(option == opt1 || option == opt2 || option == opt3 || option == opt4); \
|
||||||
|
setErrorBuffer(); \
|
||||||
|
return check_easy_code(curl_easy_setopt(mEasyHandle, option, parameter)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_FUNCTION_SETOPT1(curl_debug_callback, CURLOPT_DEBUGFUNCTION)
|
||||||
|
DEFINE_FUNCTION_SETOPT4(curl_write_callback, CURLOPT_HEADERFUNCTION, CURLOPT_WRITEFUNCTION, CURLOPT_INTERLEAVEFUNCTION, CURLOPT_READFUNCTION)
|
||||||
|
//DEFINE_FUNCTION_SETOPT1(curl_read_callback, CURLOPT_READFUNCTION)
|
||||||
|
DEFINE_FUNCTION_SETOPT1(curl_ssl_ctx_callback, CURLOPT_SSL_CTX_FUNCTION)
|
||||||
|
DEFINE_FUNCTION_SETOPT3(curl_conv_callback, CURLOPT_CONV_FROM_NETWORK_FUNCTION, CURLOPT_CONV_TO_NETWORK_FUNCTION, CURLOPT_CONV_FROM_UTF8_FUNCTION)
|
||||||
|
#if 0 // Not used by the viewer.
|
||||||
|
DEFINE_FUNCTION_SETOPT1(curl_progress_callback, CURLOPT_PROGRESSFUNCTION)
|
||||||
|
DEFINE_FUNCTION_SETOPT1(curl_seek_callback, CURLOPT_SEEKFUNCTION)
|
||||||
|
DEFINE_FUNCTION_SETOPT1(curl_ioctl_callback, CURLOPT_IOCTLFUNCTION)
|
||||||
|
DEFINE_FUNCTION_SETOPT1(curl_sockopt_callback, CURLOPT_SOCKOPTFUNCTION)
|
||||||
|
DEFINE_FUNCTION_SETOPT1(curl_opensocket_callback, CURLOPT_OPENSOCKETFUNCTION)
|
||||||
|
DEFINE_FUNCTION_SETOPT1(curl_closesocket_callback, CURLOPT_CLOSESOCKETFUNCTION)
|
||||||
|
DEFINE_FUNCTION_SETOPT1(curl_sshkeycallback, CURLOPT_SSH_KEYFUNCTION)
|
||||||
|
DEFINE_FUNCTION_SETOPT1(curl_chunk_bgn_callback, CURLOPT_CHUNK_BGN_FUNCTION)
|
||||||
|
DEFINE_FUNCTION_SETOPT1(curl_chunk_end_callback, CURLOPT_CHUNK_END_FUNCTION)
|
||||||
|
DEFINE_FUNCTION_SETOPT1(curl_fnmatch_callback, CURLOPT_FNMATCH_FUNCTION)
|
||||||
|
#endif
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// CurlEasyReqest
|
// CurlEasyRequest
|
||||||
|
|
||||||
void CurlEasyRequest::setoptString(CURLoption option, std::string const& value)
|
void CurlEasyRequest::setoptString(CURLoption option, std::string const& value)
|
||||||
{
|
{
|
||||||
@@ -729,8 +799,8 @@ void CurlEasyRequest::setoptString(CURLoption option, std::string const& value)
|
|||||||
void CurlEasyRequest::setPost(char const* postdata, S32 size)
|
void CurlEasyRequest::setPost(char const* postdata, S32 size)
|
||||||
{
|
{
|
||||||
setopt(CURLOPT_POST, 1L);
|
setopt(CURLOPT_POST, 1L);
|
||||||
setopt(CURLOPT_POSTFIELDS, static_cast<void*>(const_cast<char*>(postdata)));
|
|
||||||
setopt(CURLOPT_POSTFIELDSIZE, size);
|
setopt(CURLOPT_POSTFIELDSIZE, size);
|
||||||
|
setopt(CURLOPT_POSTFIELDS, postdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadSafeCurlEasyRequest* CurlEasyRequest::get_lockobj(void)
|
ThreadSafeCurlEasyRequest* CurlEasyRequest::get_lockobj(void)
|
||||||
|
|||||||
@@ -59,6 +59,9 @@ void stopCurlThread(void);
|
|||||||
class ThreadSafeCurlEasyRequest;
|
class ThreadSafeCurlEasyRequest;
|
||||||
class ThreadSafeBufferedCurlEasyRequest;
|
class ThreadSafeBufferedCurlEasyRequest;
|
||||||
|
|
||||||
|
#define DECLARE_SETOPT(param_type) \
|
||||||
|
CURLcode setopt(CURLoption option, param_type parameter)
|
||||||
|
|
||||||
// This class wraps CURL*'s.
|
// This class wraps CURL*'s.
|
||||||
// It guarantees that a pointer is cleaned up when no longer needed, as required by libcurl.
|
// It guarantees that a pointer is cleaned up when no longer needed, as required by libcurl.
|
||||||
class CurlEasyHandle : public boost::noncopyable, protected AICurlEasyHandleEvents {
|
class CurlEasyHandle : public boost::noncopyable, protected AICurlEasyHandleEvents {
|
||||||
@@ -75,8 +78,31 @@ class CurlEasyHandle : public boost::noncopyable, protected AICurlEasyHandleEven
|
|||||||
void reset(void) { llassert(!mActiveMultiHandle); curl_easy_reset(mEasyHandle); }
|
void reset(void) { llassert(!mActiveMultiHandle); curl_easy_reset(mEasyHandle); }
|
||||||
|
|
||||||
// Set options for a curl easy handle.
|
// Set options for a curl easy handle.
|
||||||
template<typename BUILTIN>
|
DECLARE_SETOPT(long);
|
||||||
CURLcode setopt(CURLoption option, BUILTIN parameter);
|
DECLARE_SETOPT(long long);
|
||||||
|
DECLARE_SETOPT(void const*);
|
||||||
|
DECLARE_SETOPT(curl_debug_callback);
|
||||||
|
DECLARE_SETOPT(curl_write_callback);
|
||||||
|
//DECLARE_SETOPT(curl_read_callback); Same type as curl_write_callback
|
||||||
|
DECLARE_SETOPT(curl_ssl_ctx_callback);
|
||||||
|
DECLARE_SETOPT(curl_conv_callback);
|
||||||
|
#if 0 // Not used by the viewer.
|
||||||
|
DECLARE_SETOPT(curl_progress_callback);
|
||||||
|
DECLARE_SETOPT(curl_seek_callback);
|
||||||
|
DECLARE_SETOPT(curl_ioctl_callback);
|
||||||
|
DECLARE_SETOPT(curl_sockopt_callback);
|
||||||
|
DECLARE_SETOPT(curl_opensocket_callback);
|
||||||
|
DECLARE_SETOPT(curl_closesocket_callback);
|
||||||
|
DECLARE_SETOPT(curl_sshkeycallback);
|
||||||
|
DECLARE_SETOPT(curl_chunk_bgn_callback);
|
||||||
|
DECLARE_SETOPT(curl_chunk_end_callback);
|
||||||
|
DECLARE_SETOPT(curl_fnmatch_callback);
|
||||||
|
#endif
|
||||||
|
#if __LP64__ // sizeof(long) > sizeof(S32), see http://en.cppreference.com/w/cpp/language/types
|
||||||
|
// Automatically cast small int types to a long if they differ in size.
|
||||||
|
CURLcode setopt(CURLoption option, U32 parameter) { return setopt(option, (long)parameter); }
|
||||||
|
CURLcode setopt(CURLoption option, S32 parameter) { return setopt(option, (long)parameter); }
|
||||||
|
#endif
|
||||||
|
|
||||||
// Clone a libcurl session handle using all the options previously set.
|
// Clone a libcurl session handle using all the options previously set.
|
||||||
//CurlEasyHandle(CurlEasyHandle const& orig);
|
//CurlEasyHandle(CurlEasyHandle const& orig);
|
||||||
@@ -160,14 +186,6 @@ class CurlEasyHandle : public boost::noncopyable, protected AICurlEasyHandleEven
|
|||||||
static char* getTLErrorBuffer(void);
|
static char* getTLErrorBuffer(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BUILTIN>
|
|
||||||
CURLcode CurlEasyHandle::setopt(CURLoption option, BUILTIN parameter)
|
|
||||||
{
|
|
||||||
llassert(!mActiveMultiHandle);
|
|
||||||
setErrorBuffer();
|
|
||||||
return check_easy_code(curl_easy_setopt(mEasyHandle, option, parameter));
|
|
||||||
}
|
|
||||||
|
|
||||||
// CurlEasyRequest adds a slightly more powerful interface that can be used
|
// CurlEasyRequest adds a slightly more powerful interface that can be used
|
||||||
// to set the options on a curl easy handle.
|
// to set the options on a curl easy handle.
|
||||||
//
|
//
|
||||||
@@ -397,16 +415,41 @@ class CurlMultiHandle : public boost::noncopyable {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// Set options for a curl multi handle.
|
// Set options for a curl multi handle.
|
||||||
template<typename BUILTIN>
|
CURLMcode setopt(CURLMoption option, long parameter);
|
||||||
CURLMcode setopt(CURLMoption option, BUILTIN parameter);
|
CURLMcode setopt(CURLMoption option, curl_socket_callback parameter);
|
||||||
|
CURLMcode setopt(CURLMoption option, curl_multi_timer_callback parameter);
|
||||||
|
CURLMcode setopt(CURLMoption option, void* parameter);
|
||||||
|
|
||||||
// Returns total number of existing CURLM* handles (excluding ones created outside this class).
|
// Returns total number of existing CURLM* handles (excluding ones created outside this class).
|
||||||
static U32 getTotalMultiHandles(void) { return sTotalMultiHandles; }
|
static U32 getTotalMultiHandles(void) { return sTotalMultiHandles; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BUILTIN>
|
// Overload the setopt methods in order to enforce the correct types (ie, convert an int to a long).
|
||||||
CURLMcode CurlMultiHandle::setopt(CURLMoption option, BUILTIN parameter)
|
|
||||||
|
// curl_multi_setopt may only be passed a long,
|
||||||
|
inline CURLMcode CurlMultiHandle::setopt(CURLMoption option, long parameter)
|
||||||
{
|
{
|
||||||
|
llassert(option == CURLMOPT_MAXCONNECTS || option == CURLMOPT_PIPELINING);
|
||||||
|
return check_multi_code(curl_multi_setopt(mMultiHandle, option, parameter));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... or a function pointer,
|
||||||
|
inline CURLMcode CurlMultiHandle::setopt(CURLMoption option, curl_socket_callback parameter)
|
||||||
|
{
|
||||||
|
llassert(option == CURLMOPT_SOCKETFUNCTION);
|
||||||
|
return check_multi_code(curl_multi_setopt(mMultiHandle, option, parameter));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline CURLMcode CurlMultiHandle::setopt(CURLMoption option, curl_multi_timer_callback parameter)
|
||||||
|
{
|
||||||
|
llassert(option == CURLMOPT_TIMERFUNCTION);
|
||||||
|
return check_multi_code(curl_multi_setopt(mMultiHandle, option, parameter));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... or an object pointer.
|
||||||
|
inline CURLMcode CurlMultiHandle::setopt(CURLMoption option, void* parameter)
|
||||||
|
{
|
||||||
|
llassert(option == CURLMOPT_SOCKETDATA || option == CURLMOPT_TIMERDATA);
|
||||||
return check_multi_code(curl_multi_setopt(mMultiHandle, option, parameter));
|
return check_multi_code(curl_multi_setopt(mMultiHandle, option, parameter));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -446,7 +446,7 @@ static LLSD blocking_request(
|
|||||||
std::string body_str;
|
std::string body_str;
|
||||||
|
|
||||||
// * Set curl handle options
|
// * Set curl handle options
|
||||||
curlEasyRequest_w->setopt(CURLOPT_TIMEOUT, timeout); // seconds, see warning at top of function.
|
curlEasyRequest_w->setopt(CURLOPT_TIMEOUT, (long)timeout); // seconds, see warning at top of function.
|
||||||
curlEasyRequest_w->setWriteCallback(&LLHTTPBuffer::curl_write, &http_buffer);
|
curlEasyRequest_w->setWriteCallback(&LLHTTPBuffer::curl_write, &http_buffer);
|
||||||
|
|
||||||
// * Setup headers.
|
// * Setup headers.
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip)
|
|||||||
if (mRequestText)
|
if (mRequestText)
|
||||||
{
|
{
|
||||||
Dout(dc::curl, "Writing " << mRequestTextSize << " bytes: \"" << libcwd::buf2str(mRequestText, mRequestTextSize) << "\".");;
|
Dout(dc::curl, "Writing " << mRequestTextSize << " bytes: \"" << libcwd::buf2str(mRequestText, mRequestTextSize) << "\".");;
|
||||||
curlEasyRequest_w->setopt(CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)mRequestTextSize);
|
curlEasyRequest_w->setopt(CURLOPT_POSTFIELDSIZE, mRequestTextSize);
|
||||||
curlEasyRequest_w->setoptString(CURLOPT_COPYPOSTFIELDS, mRequestText);
|
curlEasyRequest_w->setoptString(CURLOPT_COPYPOSTFIELDS, mRequestText);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -36,9 +36,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "linden_common.h"
|
#include "linden_common.h"
|
||||||
# include <set>
|
#include <set>
|
||||||
|
|
||||||
#include "volume_catcher.h"
|
#include "volume_catcher.h"
|
||||||
|
#include "llaprpool.h"
|
||||||
|
|
||||||
#ifndef LL_WINDOWS
|
#ifndef LL_WINDOWS
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -53,7 +54,6 @@ extern "C" {
|
|||||||
#include <pulse/subscribe.h>
|
#include <pulse/subscribe.h>
|
||||||
#include <pulse/glib-mainloop.h> // There's no special reason why we want the *glib* PA mainloop, but the generic polling implementation seems broken.
|
#include <pulse/glib-mainloop.h> // There's no special reason why we want the *glib* PA mainloop, but the generic polling implementation seems broken.
|
||||||
|
|
||||||
#include "llaprpool.h"
|
|
||||||
#include "apr_dso.h"
|
#include "apr_dso.h"
|
||||||
#ifdef LL_STANDALONE
|
#ifdef LL_STANDALONE
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|||||||
Reference in New Issue
Block a user