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)
|
||||
{
|
||||
@@ -729,8 +799,8 @@ void CurlEasyRequest::setoptString(CURLoption option, std::string const& value)
|
||||
void CurlEasyRequest::setPost(char const* postdata, S32 size)
|
||||
{
|
||||
setopt(CURLOPT_POST, 1L);
|
||||
setopt(CURLOPT_POSTFIELDS, static_cast<void*>(const_cast<char*>(postdata)));
|
||||
setopt(CURLOPT_POSTFIELDSIZE, size);
|
||||
setopt(CURLOPT_POSTFIELDS, postdata);
|
||||
}
|
||||
|
||||
ThreadSafeCurlEasyRequest* CurlEasyRequest::get_lockobj(void)
|
||||
|
||||
@@ -59,6 +59,9 @@ void stopCurlThread(void);
|
||||
class ThreadSafeCurlEasyRequest;
|
||||
class ThreadSafeBufferedCurlEasyRequest;
|
||||
|
||||
#define DECLARE_SETOPT(param_type) \
|
||||
CURLcode setopt(CURLoption option, param_type parameter)
|
||||
|
||||
// This class wraps CURL*'s.
|
||||
// It guarantees that a pointer is cleaned up when no longer needed, as required by libcurl.
|
||||
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); }
|
||||
|
||||
// Set options for a curl easy handle.
|
||||
template<typename BUILTIN>
|
||||
CURLcode setopt(CURLoption option, BUILTIN parameter);
|
||||
DECLARE_SETOPT(long);
|
||||
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.
|
||||
//CurlEasyHandle(CurlEasyHandle const& orig);
|
||||
@@ -160,14 +186,6 @@ class CurlEasyHandle : public boost::noncopyable, protected AICurlEasyHandleEven
|
||||
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
|
||||
// to set the options on a curl easy handle.
|
||||
//
|
||||
@@ -397,16 +415,41 @@ class CurlMultiHandle : public boost::noncopyable {
|
||||
|
||||
public:
|
||||
// Set options for a curl multi handle.
|
||||
template<typename BUILTIN>
|
||||
CURLMcode setopt(CURLMoption option, BUILTIN parameter);
|
||||
CURLMcode setopt(CURLMoption option, long 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).
|
||||
static U32 getTotalMultiHandles(void) { return sTotalMultiHandles; }
|
||||
};
|
||||
|
||||
template<typename BUILTIN>
|
||||
CURLMcode CurlMultiHandle::setopt(CURLMoption option, BUILTIN parameter)
|
||||
// Overload the setopt methods in order to enforce the correct types (ie, convert an int to a long).
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
|
||||
@@ -446,7 +446,7 @@ static LLSD blocking_request(
|
||||
std::string body_str;
|
||||
|
||||
// * 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);
|
||||
|
||||
// * Setup headers.
|
||||
|
||||
@@ -263,7 +263,7 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip)
|
||||
if (mRequestText)
|
||||
{
|
||||
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);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -36,9 +36,10 @@
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
# include <set>
|
||||
#include <set>
|
||||
|
||||
#include "volume_catcher.h"
|
||||
#include "llaprpool.h"
|
||||
|
||||
#ifndef LL_WINDOWS
|
||||
#include <unistd.h>
|
||||
@@ -53,7 +54,6 @@ extern "C" {
|
||||
#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 "llaprpool.h"
|
||||
#include "apr_dso.h"
|
||||
#ifdef LL_STANDALONE
|
||||
#include <dlfcn.h>
|
||||
|
||||
Reference in New Issue
Block a user